chore: update prettier (#5412)
This commit is contained in:
committed by
GitHub
parent
46738492a0
commit
39f113715a
9
packages/netlify-cms-core/index.d.ts
vendored
9
packages/netlify-cms-core/index.d.ts
vendored
@ -516,9 +516,12 @@ declare module 'netlify-cms-core' {
|
||||
};
|
||||
}
|
||||
|
||||
type GetAssetFunction = (
|
||||
asset: string,
|
||||
) => { url: string; path: string; field?: any; fileObj: File };
|
||||
type GetAssetFunction = (asset: string) => {
|
||||
url: string;
|
||||
path: string;
|
||||
field?: any;
|
||||
fileObj: File;
|
||||
};
|
||||
|
||||
export type PreviewTemplateComponentProps = {
|
||||
entry: Map<string, any>;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,9 +9,8 @@ import { State } from '../../types/redux';
|
||||
import AssetProxy from '../../valueObjects/AssetProxy';
|
||||
|
||||
const middlewares = [thunk];
|
||||
const mockStore = configureMockStore<Partial<State>, ThunkDispatch<State, {}, AnyAction>>(
|
||||
middlewares,
|
||||
);
|
||||
const mockStore =
|
||||
configureMockStore<Partial<State>, ThunkDispatch<State, {}, AnyAction>>(middlewares);
|
||||
const mockedSelectMediaFilePath = mocked(selectMediaFilePath);
|
||||
|
||||
jest.mock('../../reducers/entries');
|
||||
|
@ -1,326 +1,326 @@
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
import thunk from 'redux-thunk';
|
||||
import { List, Map } from 'immutable';
|
||||
import { insertMedia, persistMedia, deleteMedia } from '../mediaLibrary';
|
||||
|
||||
jest.mock('../../backend');
|
||||
jest.mock('../waitUntil');
|
||||
jest.mock('netlify-cms-lib-util', () => {
|
||||
const lib = jest.requireActual('netlify-cms-lib-util');
|
||||
return {
|
||||
...lib,
|
||||
getBlobSHA: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
const middlewares = [thunk];
|
||||
const mockStore = configureMockStore(middlewares);
|
||||
|
||||
describe('mediaLibrary', () => {
|
||||
describe('insertMedia', () => {
|
||||
it('should return mediaPath as string when string is given', () => {
|
||||
const store = mockStore({
|
||||
config: {
|
||||
public_folder: '/media',
|
||||
},
|
||||
collections: Map({
|
||||
posts: Map({ name: 'posts' }),
|
||||
}),
|
||||
entryDraft: Map({
|
||||
entry: Map({ isPersisting: false, collection: 'posts' }),
|
||||
}),
|
||||
});
|
||||
|
||||
store.dispatch(insertMedia('foo.png'));
|
||||
expect(store.getActions()[0]).toEqual({
|
||||
type: 'MEDIA_INSERT',
|
||||
payload: { mediaPath: '/media/foo.png' },
|
||||
});
|
||||
});
|
||||
|
||||
it('should return mediaPath as array of strings when array of strings is given', () => {
|
||||
const store = mockStore({
|
||||
config: {
|
||||
public_folder: '/media',
|
||||
},
|
||||
collections: Map({
|
||||
posts: Map({ name: 'posts' }),
|
||||
}),
|
||||
entryDraft: Map({
|
||||
entry: Map({ isPersisting: false, collection: 'posts' }),
|
||||
}),
|
||||
});
|
||||
|
||||
store.dispatch(insertMedia(['foo.png']));
|
||||
expect(store.getActions()[0]).toEqual({
|
||||
type: 'MEDIA_INSERT',
|
||||
payload: { mediaPath: ['/media/foo.png'] },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const { currentBackend } = require('coreSrc/backend');
|
||||
|
||||
const backend = {
|
||||
persistMedia: jest.fn(() => ({ id: 'id' })),
|
||||
deleteMedia: jest.fn(),
|
||||
};
|
||||
|
||||
currentBackend.mockReturnValue(backend);
|
||||
|
||||
describe('persistMedia', () => {
|
||||
global.URL = { createObjectURL: jest.fn().mockReturnValue('displayURL') };
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should not persist media when editing draft', () => {
|
||||
const { getBlobSHA } = require('netlify-cms-lib-util');
|
||||
|
||||
getBlobSHA.mockReturnValue('000000000000000');
|
||||
|
||||
const store = mockStore({
|
||||
config: {
|
||||
media_folder: 'static/media',
|
||||
slug: {
|
||||
encoding: 'unicode',
|
||||
clean_accents: false,
|
||||
sanitize_replacement: '-',
|
||||
},
|
||||
},
|
||||
collections: Map({
|
||||
posts: Map({ name: 'posts' }),
|
||||
}),
|
||||
integrations: Map(),
|
||||
mediaLibrary: Map({
|
||||
files: List(),
|
||||
}),
|
||||
entryDraft: Map({
|
||||
entry: Map({ isPersisting: false, collection: 'posts' }),
|
||||
}),
|
||||
});
|
||||
|
||||
const file = new File([''], 'name.png');
|
||||
|
||||
return store.dispatch(persistMedia(file)).then(() => {
|
||||
const actions = store.getActions();
|
||||
|
||||
expect(actions).toHaveLength(2);
|
||||
expect(actions[0].type).toEqual('ADD_ASSET');
|
||||
expect(actions[0].payload).toEqual(
|
||||
expect.objectContaining({
|
||||
path: 'static/media/name.png',
|
||||
}),
|
||||
);
|
||||
expect(actions[1].type).toEqual('ADD_DRAFT_ENTRY_MEDIA_FILE');
|
||||
expect(actions[1].payload).toEqual(
|
||||
expect.objectContaining({
|
||||
draft: true,
|
||||
id: '000000000000000',
|
||||
path: 'static/media/name.png',
|
||||
size: file.size,
|
||||
name: file.name,
|
||||
}),
|
||||
);
|
||||
|
||||
expect(getBlobSHA).toHaveBeenCalledTimes(1);
|
||||
expect(getBlobSHA).toHaveBeenCalledWith(file);
|
||||
expect(backend.persistMedia).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('should persist media when not editing draft', () => {
|
||||
const store = mockStore({
|
||||
config: {
|
||||
media_folder: 'static/media',
|
||||
slug: {
|
||||
encoding: 'unicode',
|
||||
clean_accents: false,
|
||||
sanitize_replacement: '-',
|
||||
},
|
||||
},
|
||||
collections: Map({
|
||||
posts: Map({ name: 'posts' }),
|
||||
}),
|
||||
integrations: Map(),
|
||||
mediaLibrary: Map({
|
||||
files: List(),
|
||||
}),
|
||||
entryDraft: Map({
|
||||
entry: Map(),
|
||||
}),
|
||||
});
|
||||
|
||||
const file = new File([''], 'name.png');
|
||||
|
||||
return store.dispatch(persistMedia(file)).then(() => {
|
||||
const actions = store.getActions();
|
||||
|
||||
expect(actions).toHaveLength(3);
|
||||
|
||||
expect(actions).toHaveLength(3);
|
||||
expect(actions[0]).toEqual({ type: 'MEDIA_PERSIST_REQUEST' });
|
||||
expect(actions[1].type).toEqual('ADD_ASSET');
|
||||
expect(actions[1].payload).toEqual(
|
||||
expect.objectContaining({
|
||||
path: 'static/media/name.png',
|
||||
}),
|
||||
);
|
||||
expect(actions[2]).toEqual({
|
||||
type: 'MEDIA_PERSIST_SUCCESS',
|
||||
payload: {
|
||||
file: { id: 'id' },
|
||||
},
|
||||
});
|
||||
|
||||
expect(backend.persistMedia).toHaveBeenCalledTimes(1);
|
||||
expect(backend.persistMedia).toHaveBeenCalledWith(
|
||||
store.getState().config,
|
||||
expect.objectContaining({
|
||||
path: 'static/media/name.png',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should sanitize media name if needed when persisting', () => {
|
||||
const store = mockStore({
|
||||
config: {
|
||||
media_folder: 'static/media',
|
||||
slug: {
|
||||
encoding: 'ascii',
|
||||
clean_accents: true,
|
||||
sanitize_replacement: '_',
|
||||
},
|
||||
},
|
||||
collections: Map({
|
||||
posts: Map({ name: 'posts' }),
|
||||
}),
|
||||
integrations: Map(),
|
||||
mediaLibrary: Map({
|
||||
files: List(),
|
||||
}),
|
||||
entryDraft: Map({
|
||||
entry: Map(),
|
||||
}),
|
||||
});
|
||||
|
||||
const file = new File([''], 'abc DEF éâçÖ $;, .png');
|
||||
|
||||
return store.dispatch(persistMedia(file)).then(() => {
|
||||
const actions = store.getActions();
|
||||
|
||||
expect(actions).toHaveLength(3);
|
||||
|
||||
expect(actions[0]).toEqual({ type: 'MEDIA_PERSIST_REQUEST' });
|
||||
|
||||
expect(actions[1].type).toEqual('ADD_ASSET');
|
||||
expect(actions[1].payload).toEqual(
|
||||
expect.objectContaining({
|
||||
path: 'static/media/abc_def_eaco_.png',
|
||||
}),
|
||||
);
|
||||
|
||||
expect(actions[2]).toEqual({
|
||||
type: 'MEDIA_PERSIST_SUCCESS',
|
||||
payload: {
|
||||
file: { id: 'id' },
|
||||
},
|
||||
});
|
||||
|
||||
expect(backend.persistMedia).toHaveBeenCalledTimes(1);
|
||||
expect(backend.persistMedia).toHaveBeenCalledWith(
|
||||
store.getState().config,
|
||||
expect.objectContaining({
|
||||
path: 'static/media/abc_def_eaco_.png',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteMedia', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should delete non draft file', () => {
|
||||
const store = mockStore({
|
||||
config: {
|
||||
publish_mode: 'editorial_workflow',
|
||||
},
|
||||
collections: Map(),
|
||||
integrations: Map(),
|
||||
mediaLibrary: Map({
|
||||
files: List(),
|
||||
}),
|
||||
entryDraft: Map({
|
||||
entry: Map({ isPersisting: false }),
|
||||
}),
|
||||
});
|
||||
|
||||
const file = { name: 'name.png', id: 'id', path: 'static/media/name.png', draft: false };
|
||||
|
||||
return store.dispatch(deleteMedia(file)).then(() => {
|
||||
const actions = store.getActions();
|
||||
|
||||
expect(actions).toHaveLength(4);
|
||||
expect(actions[0]).toEqual({ type: 'MEDIA_DELETE_REQUEST' });
|
||||
expect(actions[1]).toEqual({
|
||||
type: 'REMOVE_ASSET',
|
||||
payload: 'static/media/name.png',
|
||||
});
|
||||
expect(actions[2]).toEqual({
|
||||
type: 'MEDIA_DELETE_SUCCESS',
|
||||
payload: { file },
|
||||
});
|
||||
expect(actions[3]).toEqual({
|
||||
type: 'REMOVE_DRAFT_ENTRY_MEDIA_FILE',
|
||||
payload: { id: 'id' },
|
||||
});
|
||||
|
||||
expect(backend.deleteMedia).toHaveBeenCalledTimes(1);
|
||||
expect(backend.deleteMedia).toHaveBeenCalledWith(
|
||||
store.getState().config,
|
||||
'static/media/name.png',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not delete a draft file', () => {
|
||||
const store = mockStore({
|
||||
config: {
|
||||
publish_mode: 'editorial_workflow',
|
||||
},
|
||||
collections: Map(),
|
||||
integrations: Map(),
|
||||
mediaLibrary: Map({
|
||||
files: List(),
|
||||
}),
|
||||
entryDraft: Map({
|
||||
entry: Map({ isPersisting: false }),
|
||||
}),
|
||||
});
|
||||
|
||||
const file = { name: 'name.png', id: 'id', path: 'static/media/name.png', draft: true };
|
||||
|
||||
return store.dispatch(deleteMedia(file)).then(() => {
|
||||
const actions = store.getActions();
|
||||
|
||||
expect(actions).toHaveLength(2);
|
||||
expect(actions[0]).toEqual({
|
||||
type: 'REMOVE_ASSET',
|
||||
payload: 'static/media/name.png',
|
||||
});
|
||||
|
||||
expect(actions[1]).toEqual({
|
||||
type: 'REMOVE_DRAFT_ENTRY_MEDIA_FILE',
|
||||
payload: { id: 'id' },
|
||||
});
|
||||
|
||||
expect(backend.deleteMedia).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
import thunk from 'redux-thunk';
|
||||
import { List, Map } from 'immutable';
|
||||
import { insertMedia, persistMedia, deleteMedia } from '../mediaLibrary';
|
||||
|
||||
jest.mock('../../backend');
|
||||
jest.mock('../waitUntil');
|
||||
jest.mock('netlify-cms-lib-util', () => {
|
||||
const lib = jest.requireActual('netlify-cms-lib-util');
|
||||
return {
|
||||
...lib,
|
||||
getBlobSHA: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
const middlewares = [thunk];
|
||||
const mockStore = configureMockStore(middlewares);
|
||||
|
||||
describe('mediaLibrary', () => {
|
||||
describe('insertMedia', () => {
|
||||
it('should return mediaPath as string when string is given', () => {
|
||||
const store = mockStore({
|
||||
config: {
|
||||
public_folder: '/media',
|
||||
},
|
||||
collections: Map({
|
||||
posts: Map({ name: 'posts' }),
|
||||
}),
|
||||
entryDraft: Map({
|
||||
entry: Map({ isPersisting: false, collection: 'posts' }),
|
||||
}),
|
||||
});
|
||||
|
||||
store.dispatch(insertMedia('foo.png'));
|
||||
expect(store.getActions()[0]).toEqual({
|
||||
type: 'MEDIA_INSERT',
|
||||
payload: { mediaPath: '/media/foo.png' },
|
||||
});
|
||||
});
|
||||
|
||||
it('should return mediaPath as array of strings when array of strings is given', () => {
|
||||
const store = mockStore({
|
||||
config: {
|
||||
public_folder: '/media',
|
||||
},
|
||||
collections: Map({
|
||||
posts: Map({ name: 'posts' }),
|
||||
}),
|
||||
entryDraft: Map({
|
||||
entry: Map({ isPersisting: false, collection: 'posts' }),
|
||||
}),
|
||||
});
|
||||
|
||||
store.dispatch(insertMedia(['foo.png']));
|
||||
expect(store.getActions()[0]).toEqual({
|
||||
type: 'MEDIA_INSERT',
|
||||
payload: { mediaPath: ['/media/foo.png'] },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const { currentBackend } = require('coreSrc/backend');
|
||||
|
||||
const backend = {
|
||||
persistMedia: jest.fn(() => ({ id: 'id' })),
|
||||
deleteMedia: jest.fn(),
|
||||
};
|
||||
|
||||
currentBackend.mockReturnValue(backend);
|
||||
|
||||
describe('persistMedia', () => {
|
||||
global.URL = { createObjectURL: jest.fn().mockReturnValue('displayURL') };
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should not persist media when editing draft', () => {
|
||||
const { getBlobSHA } = require('netlify-cms-lib-util');
|
||||
|
||||
getBlobSHA.mockReturnValue('000000000000000');
|
||||
|
||||
const store = mockStore({
|
||||
config: {
|
||||
media_folder: 'static/media',
|
||||
slug: {
|
||||
encoding: 'unicode',
|
||||
clean_accents: false,
|
||||
sanitize_replacement: '-',
|
||||
},
|
||||
},
|
||||
collections: Map({
|
||||
posts: Map({ name: 'posts' }),
|
||||
}),
|
||||
integrations: Map(),
|
||||
mediaLibrary: Map({
|
||||
files: List(),
|
||||
}),
|
||||
entryDraft: Map({
|
||||
entry: Map({ isPersisting: false, collection: 'posts' }),
|
||||
}),
|
||||
});
|
||||
|
||||
const file = new File([''], 'name.png');
|
||||
|
||||
return store.dispatch(persistMedia(file)).then(() => {
|
||||
const actions = store.getActions();
|
||||
|
||||
expect(actions).toHaveLength(2);
|
||||
expect(actions[0].type).toEqual('ADD_ASSET');
|
||||
expect(actions[0].payload).toEqual(
|
||||
expect.objectContaining({
|
||||
path: 'static/media/name.png',
|
||||
}),
|
||||
);
|
||||
expect(actions[1].type).toEqual('ADD_DRAFT_ENTRY_MEDIA_FILE');
|
||||
expect(actions[1].payload).toEqual(
|
||||
expect.objectContaining({
|
||||
draft: true,
|
||||
id: '000000000000000',
|
||||
path: 'static/media/name.png',
|
||||
size: file.size,
|
||||
name: file.name,
|
||||
}),
|
||||
);
|
||||
|
||||
expect(getBlobSHA).toHaveBeenCalledTimes(1);
|
||||
expect(getBlobSHA).toHaveBeenCalledWith(file);
|
||||
expect(backend.persistMedia).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('should persist media when not editing draft', () => {
|
||||
const store = mockStore({
|
||||
config: {
|
||||
media_folder: 'static/media',
|
||||
slug: {
|
||||
encoding: 'unicode',
|
||||
clean_accents: false,
|
||||
sanitize_replacement: '-',
|
||||
},
|
||||
},
|
||||
collections: Map({
|
||||
posts: Map({ name: 'posts' }),
|
||||
}),
|
||||
integrations: Map(),
|
||||
mediaLibrary: Map({
|
||||
files: List(),
|
||||
}),
|
||||
entryDraft: Map({
|
||||
entry: Map(),
|
||||
}),
|
||||
});
|
||||
|
||||
const file = new File([''], 'name.png');
|
||||
|
||||
return store.dispatch(persistMedia(file)).then(() => {
|
||||
const actions = store.getActions();
|
||||
|
||||
expect(actions).toHaveLength(3);
|
||||
|
||||
expect(actions).toHaveLength(3);
|
||||
expect(actions[0]).toEqual({ type: 'MEDIA_PERSIST_REQUEST' });
|
||||
expect(actions[1].type).toEqual('ADD_ASSET');
|
||||
expect(actions[1].payload).toEqual(
|
||||
expect.objectContaining({
|
||||
path: 'static/media/name.png',
|
||||
}),
|
||||
);
|
||||
expect(actions[2]).toEqual({
|
||||
type: 'MEDIA_PERSIST_SUCCESS',
|
||||
payload: {
|
||||
file: { id: 'id' },
|
||||
},
|
||||
});
|
||||
|
||||
expect(backend.persistMedia).toHaveBeenCalledTimes(1);
|
||||
expect(backend.persistMedia).toHaveBeenCalledWith(
|
||||
store.getState().config,
|
||||
expect.objectContaining({
|
||||
path: 'static/media/name.png',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should sanitize media name if needed when persisting', () => {
|
||||
const store = mockStore({
|
||||
config: {
|
||||
media_folder: 'static/media',
|
||||
slug: {
|
||||
encoding: 'ascii',
|
||||
clean_accents: true,
|
||||
sanitize_replacement: '_',
|
||||
},
|
||||
},
|
||||
collections: Map({
|
||||
posts: Map({ name: 'posts' }),
|
||||
}),
|
||||
integrations: Map(),
|
||||
mediaLibrary: Map({
|
||||
files: List(),
|
||||
}),
|
||||
entryDraft: Map({
|
||||
entry: Map(),
|
||||
}),
|
||||
});
|
||||
|
||||
const file = new File([''], 'abc DEF éâçÖ $;, .png');
|
||||
|
||||
return store.dispatch(persistMedia(file)).then(() => {
|
||||
const actions = store.getActions();
|
||||
|
||||
expect(actions).toHaveLength(3);
|
||||
|
||||
expect(actions[0]).toEqual({ type: 'MEDIA_PERSIST_REQUEST' });
|
||||
|
||||
expect(actions[1].type).toEqual('ADD_ASSET');
|
||||
expect(actions[1].payload).toEqual(
|
||||
expect.objectContaining({
|
||||
path: 'static/media/abc_def_eaco_.png',
|
||||
}),
|
||||
);
|
||||
|
||||
expect(actions[2]).toEqual({
|
||||
type: 'MEDIA_PERSIST_SUCCESS',
|
||||
payload: {
|
||||
file: { id: 'id' },
|
||||
},
|
||||
});
|
||||
|
||||
expect(backend.persistMedia).toHaveBeenCalledTimes(1);
|
||||
expect(backend.persistMedia).toHaveBeenCalledWith(
|
||||
store.getState().config,
|
||||
expect.objectContaining({
|
||||
path: 'static/media/abc_def_eaco_.png',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteMedia', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should delete non draft file', () => {
|
||||
const store = mockStore({
|
||||
config: {
|
||||
publish_mode: 'editorial_workflow',
|
||||
},
|
||||
collections: Map(),
|
||||
integrations: Map(),
|
||||
mediaLibrary: Map({
|
||||
files: List(),
|
||||
}),
|
||||
entryDraft: Map({
|
||||
entry: Map({ isPersisting: false }),
|
||||
}),
|
||||
});
|
||||
|
||||
const file = { name: 'name.png', id: 'id', path: 'static/media/name.png', draft: false };
|
||||
|
||||
return store.dispatch(deleteMedia(file)).then(() => {
|
||||
const actions = store.getActions();
|
||||
|
||||
expect(actions).toHaveLength(4);
|
||||
expect(actions[0]).toEqual({ type: 'MEDIA_DELETE_REQUEST' });
|
||||
expect(actions[1]).toEqual({
|
||||
type: 'REMOVE_ASSET',
|
||||
payload: 'static/media/name.png',
|
||||
});
|
||||
expect(actions[2]).toEqual({
|
||||
type: 'MEDIA_DELETE_SUCCESS',
|
||||
payload: { file },
|
||||
});
|
||||
expect(actions[3]).toEqual({
|
||||
type: 'REMOVE_DRAFT_ENTRY_MEDIA_FILE',
|
||||
payload: { id: 'id' },
|
||||
});
|
||||
|
||||
expect(backend.deleteMedia).toHaveBeenCalledTimes(1);
|
||||
expect(backend.deleteMedia).toHaveBeenCalledWith(
|
||||
store.getState().config,
|
||||
'static/media/name.png',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not delete a draft file', () => {
|
||||
const store = mockStore({
|
||||
config: {
|
||||
publish_mode: 'editorial_workflow',
|
||||
},
|
||||
collections: Map(),
|
||||
integrations: Map(),
|
||||
mediaLibrary: Map({
|
||||
files: List(),
|
||||
}),
|
||||
entryDraft: Map({
|
||||
entry: Map({ isPersisting: false }),
|
||||
}),
|
||||
});
|
||||
|
||||
const file = { name: 'name.png', id: 'id', path: 'static/media/name.png', draft: true };
|
||||
|
||||
return store.dispatch(deleteMedia(file)).then(() => {
|
||||
const actions = store.getActions();
|
||||
|
||||
expect(actions).toHaveLength(2);
|
||||
expect(actions[0]).toEqual({
|
||||
type: 'REMOVE_ASSET',
|
||||
payload: 'static/media/name.png',
|
||||
});
|
||||
|
||||
expect(actions[1]).toEqual({
|
||||
type: 'REMOVE_DRAFT_ENTRY_MEDIA_FILE',
|
||||
payload: { id: 'id' },
|
||||
});
|
||||
|
||||
expect(backend.deleteMedia).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -474,9 +474,11 @@ export async function handleLocalBackend(originalConfig: CmsConfig) {
|
||||
return originalConfig;
|
||||
}
|
||||
|
||||
const { proxyUrl, publish_modes: publishModes, type: backendType } = await detectProxyServer(
|
||||
originalConfig.local_backend,
|
||||
);
|
||||
const {
|
||||
proxyUrl,
|
||||
publish_modes: publishModes,
|
||||
type: backendType,
|
||||
} = await detectProxyServer(originalConfig.local_backend);
|
||||
|
||||
if (!proxyUrl) {
|
||||
return originalConfig;
|
||||
|
@ -519,7 +519,7 @@ export function unpublishPublishedEntry(collection: Collection, slug: string) {
|
||||
const state = getState();
|
||||
const backend = currentBackend(state.config);
|
||||
const entry = selectEntry(state, collection.get('name'), slug);
|
||||
const entryDraft = (Map().set('entry', entry) as unknown) as EntryDraft;
|
||||
const entryDraft = Map().set('entry', entry) as unknown as EntryDraft;
|
||||
dispatch(unpublishedEntryPersisting(collection, slug));
|
||||
return backend
|
||||
.deleteEntry(state, collection, slug)
|
||||
|
@ -1322,7 +1322,7 @@ export function resolveBackend(config: CmsConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
export const currentBackend = (function() {
|
||||
export const currentBackend = (function () {
|
||||
let backend: Backend;
|
||||
|
||||
return (config: CmsConfig) => {
|
||||
|
@ -25,7 +25,7 @@ import Header from './Header';
|
||||
|
||||
TopBarProgress.config({
|
||||
barColors: {
|
||||
'0': colors.active,
|
||||
0: colors.active,
|
||||
'1.0': colors.active,
|
||||
},
|
||||
shadowBlur: 0,
|
||||
|
@ -192,7 +192,7 @@ export class Editor extends React.Component {
|
||||
window.removeEventListener('beforeunload', this.exitBlocker);
|
||||
}
|
||||
|
||||
createBackup = debounce(function(entry, collection) {
|
||||
createBackup = debounce(function (entry, collection) {
|
||||
this.props.persistLocalBackup(entry, collection);
|
||||
}, 2000);
|
||||
|
||||
@ -202,14 +202,8 @@ export class Editor extends React.Component {
|
||||
};
|
||||
|
||||
handleChangeStatus = newStatusName => {
|
||||
const {
|
||||
entryDraft,
|
||||
updateUnpublishedEntryStatus,
|
||||
collection,
|
||||
slug,
|
||||
currentStatus,
|
||||
t,
|
||||
} = this.props;
|
||||
const { entryDraft, updateUnpublishedEntryStatus, collection, slug, currentStatus, t } =
|
||||
this.props;
|
||||
if (entryDraft.get('hasChanged')) {
|
||||
window.alert(t('editor.editor.onUpdatingWithUnsavedChanges'));
|
||||
return;
|
||||
@ -318,15 +312,8 @@ export class Editor extends React.Component {
|
||||
};
|
||||
|
||||
handleDeleteUnpublishedChanges = async () => {
|
||||
const {
|
||||
entryDraft,
|
||||
collection,
|
||||
slug,
|
||||
deleteUnpublishedEntry,
|
||||
loadEntry,
|
||||
isModification,
|
||||
t,
|
||||
} = this.props;
|
||||
const { entryDraft, collection, slug, deleteUnpublishedEntry, loadEntry, isModification, t } =
|
||||
this.props;
|
||||
if (
|
||||
entryDraft.get('hasChanged') &&
|
||||
!window.confirm(t('editor.editor.onDeleteUnpublishedChangesWithUnsavedChanges'))
|
||||
|
@ -24,10 +24,10 @@ const timestampTag = {
|
||||
tag: '!timestamp',
|
||||
test: RegExp(
|
||||
'^' +
|
||||
'([0-9]{4})-([0-9]{2})-([0-9]{2})' + // YYYY-MM-DD
|
||||
'T' + // T
|
||||
'([0-9]{2}):([0-9]{2}):([0-9]{2}(\\.[0-9]+)?)' + // HH:MM:SS(.ss)?
|
||||
'Z' + // Z
|
||||
'([0-9]{4})-([0-9]{2})-([0-9]{2})' + // YYYY-MM-DD
|
||||
'T' + // T
|
||||
'([0-9]{2}):([0-9]{2}):([0-9]{2}(\\.[0-9]+)?)' + // HH:MM:SS(.ss)?
|
||||
'Z' + // Z
|
||||
'$',
|
||||
),
|
||||
resolve: (str: string) => new Date(str),
|
||||
|
@ -20,7 +20,7 @@ export function resolveIntegrations(interationsConfig, getToken) {
|
||||
return integrationInstances;
|
||||
}
|
||||
|
||||
export const getIntegrationProvider = (function() {
|
||||
export const getIntegrationProvider = (function () {
|
||||
let integrations = null;
|
||||
|
||||
return (interationsConfig, getToken, provider) => {
|
||||
|
@ -182,7 +182,7 @@ export function previewUrlFormatter(
|
||||
let fields = entry.get('data') as Map<string, string>;
|
||||
fields = addFileTemplateFields(entry.get('path'), fields, collection.get('folder'));
|
||||
const dateFieldName = getDateField() || selectInferedField(collection, 'date');
|
||||
const date = parseDateFromEntry((entry as unknown) as Map<string, unknown>, dateFieldName);
|
||||
const date = parseDateFromEntry(entry as unknown as Map<string, unknown>, dateFieldName);
|
||||
|
||||
// Prepare and sanitize slug variables only, leave the rest of the
|
||||
// `preview_path` template as is.
|
||||
@ -213,7 +213,7 @@ export function summaryFormatter(summaryTemplate: string, entry: EntryMap, colle
|
||||
let entryData = entry.get('data');
|
||||
const date =
|
||||
parseDateFromEntry(
|
||||
(entry as unknown) as Map<string, unknown>,
|
||||
entry as unknown as Map<string, unknown>,
|
||||
selectInferedField(collection, 'date'),
|
||||
) || null;
|
||||
const identifier = entryData.getIn(keyToPathArray(selectIdentifier(collection) as string));
|
||||
@ -247,7 +247,7 @@ export function folderFormatter(
|
||||
|
||||
const date =
|
||||
parseDateFromEntry(
|
||||
(entry as unknown) as Map<string, unknown>,
|
||||
entry as unknown as Map<string, unknown>,
|
||||
selectInferedField(collection, 'date'),
|
||||
) || null;
|
||||
const identifier = fields.getIn(keyToPathArray(selectIdentifier(collection) as string));
|
||||
|
@ -36,7 +36,8 @@ export function stripProtocol(urlString: string) {
|
||||
* but JS stores strings as UTF-16/UCS-2 internally, so we should not normalize or re-encode.
|
||||
*/
|
||||
const uriChars = /[\w\-.~]/i;
|
||||
const ucsChars = /[\xA0-\u{D7FF}\u{F900}-\u{FDCF}\u{FDF0}-\u{FFEF}\u{10000}-\u{1FFFD}\u{20000}-\u{2FFFD}\u{30000}-\u{3FFFD}\u{40000}-\u{4FFFD}\u{50000}-\u{5FFFD}\u{60000}-\u{6FFFD}\u{70000}-\u{7FFFD}\u{80000}-\u{8FFFD}\u{90000}-\u{9FFFD}\u{A0000}-\u{AFFFD}\u{B0000}-\u{BFFFD}\u{C0000}-\u{CFFFD}\u{D0000}-\u{DFFFD}\u{E1000}-\u{EFFFD}]/u;
|
||||
const ucsChars =
|
||||
/[\xA0-\u{D7FF}\u{F900}-\u{FDCF}\u{FDF0}-\u{FFEF}\u{10000}-\u{1FFFD}\u{20000}-\u{2FFFD}\u{30000}-\u{3FFFD}\u{40000}-\u{4FFFD}\u{50000}-\u{5FFFD}\u{60000}-\u{6FFFD}\u{70000}-\u{7FFFD}\u{80000}-\u{8FFFD}\u{90000}-\u{9FFFD}\u{A0000}-\u{AFFFD}\u{B0000}-\u{BFFFD}\u{C0000}-\u{CFFFD}\u{D0000}-\u{DFFFD}\u{E1000}-\u{EFFFD}]/u;
|
||||
|
||||
function validURIChar(char: string) {
|
||||
return uriChars.test(char);
|
||||
@ -80,9 +81,7 @@ export function sanitizeURI(
|
||||
|
||||
// `Array.from` must be used instead of `String.split` because
|
||||
// `split` converts things like emojis into UTF-16 surrogate pairs.
|
||||
return Array.from(str)
|
||||
.map(getCharReplacer(encoding, replacement))
|
||||
.join('');
|
||||
return Array.from(str).map(getCharReplacer(encoding, replacement)).join('');
|
||||
}
|
||||
|
||||
export function sanitizeChar(char: string, options?: CmsSlug) {
|
||||
@ -95,8 +94,11 @@ export function sanitizeSlug(str: string, options?: CmsSlug) {
|
||||
throw new Error('The input slug must be a string.');
|
||||
}
|
||||
|
||||
const { encoding, clean_accents: stripDiacritics, sanitize_replacement: replacement } =
|
||||
options || {};
|
||||
const {
|
||||
encoding,
|
||||
clean_accents: stripDiacritics,
|
||||
sanitize_replacement: replacement,
|
||||
} = options || {};
|
||||
|
||||
const sanitizedSlug = flow([
|
||||
...(stripDiacritics ? [diacritics.remove] : []),
|
||||
|
@ -25,7 +25,7 @@ function handleInsert(url: string) {
|
||||
}
|
||||
|
||||
const initializeMediaLibrary = once(async function initializeMediaLibrary(name, options) {
|
||||
const lib = (getMediaLibrary(name) as unknown) as MediaLibrary | undefined;
|
||||
const lib = getMediaLibrary(name) as unknown as MediaLibrary | undefined;
|
||||
if (!lib) {
|
||||
const err = new Error(
|
||||
`Missing external media library '${name}'. Please use 'registerMediaLibrary' to register it.`,
|
||||
|
@ -368,30 +368,15 @@ describe('collections', () => {
|
||||
});
|
||||
|
||||
expect(selectField(collection, 'en.title')).toBe(
|
||||
collection
|
||||
.get('fields')
|
||||
.get(0)
|
||||
.get('fields')
|
||||
.get(0),
|
||||
collection.get('fields').get(0).get('fields').get(0),
|
||||
);
|
||||
|
||||
expect(selectField(collection, 'it.title.subTitle')).toBe(
|
||||
collection
|
||||
.get('fields')
|
||||
.get(2)
|
||||
.get('field')
|
||||
.get('fields')
|
||||
.get(0),
|
||||
collection.get('fields').get(2).get('field').get('fields').get(0),
|
||||
);
|
||||
|
||||
expect(selectField(collection, 'fr.title.variableType')).toBe(
|
||||
collection
|
||||
.get('fields')
|
||||
.get(3)
|
||||
.get('fields')
|
||||
.get(0)
|
||||
.get('types')
|
||||
.get(0),
|
||||
collection.get('fields').get(3).get('fields').get(0).get('types').get(0),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -144,10 +144,7 @@ export function selectFieldsWithMediaFolders(collection: Collection, slug: strin
|
||||
const fields = collection.get('fields').toArray();
|
||||
return getFieldsWithMediaFolders(fields);
|
||||
} else if (collection.has('files')) {
|
||||
const fields =
|
||||
getFileFromSlug(collection, slug)
|
||||
?.get('fields')
|
||||
.toArray() || [];
|
||||
const fields = getFileFromSlug(collection, slug)?.get('fields').toArray() || [];
|
||||
return getFieldsWithMediaFolders(fields);
|
||||
}
|
||||
|
||||
@ -317,16 +314,18 @@ export function selectInferedField(collection: Collection, fieldName: string) {
|
||||
if (fieldName === 'title' && collection.get('identifier_field')) {
|
||||
return selectIdentifier(collection);
|
||||
}
|
||||
const inferableField = (INFERABLE_FIELDS as Record<
|
||||
string,
|
||||
{
|
||||
type: string;
|
||||
synonyms: string[];
|
||||
secondaryTypes: string[];
|
||||
fallbackToFirstField: boolean;
|
||||
showError: boolean;
|
||||
}
|
||||
>)[fieldName];
|
||||
const inferableField = (
|
||||
INFERABLE_FIELDS as Record<
|
||||
string,
|
||||
{
|
||||
type: string;
|
||||
synonyms: string[];
|
||||
secondaryTypes: string[];
|
||||
fallbackToFirstField: boolean;
|
||||
showError: boolean;
|
||||
}
|
||||
>
|
||||
)[fieldName];
|
||||
const fields = collection.get('fields');
|
||||
let field;
|
||||
|
||||
|
@ -105,10 +105,9 @@ function persistSort(sort: Sort | undefined) {
|
||||
const storageSort: StorageSort = {};
|
||||
sort.keySeq().forEach(key => {
|
||||
const collection = key as string;
|
||||
const sortObjects = (sort
|
||||
.get(collection)
|
||||
.valueSeq()
|
||||
.toJS() as SortObject[]).map((value, index) => ({ ...value, index }));
|
||||
const sortObjects = (sort.get(collection).valueSeq().toJS() as SortObject[]).map(
|
||||
(value, index) => ({ ...value, index }),
|
||||
);
|
||||
|
||||
sortObjects.forEach(value => {
|
||||
set(storageSort, [collection, value.key], value);
|
||||
@ -333,7 +332,7 @@ function entries(
|
||||
}
|
||||
|
||||
case CHANGE_VIEW_STYLE: {
|
||||
const payload = (action.payload as unknown) as ChangeViewStylePayload;
|
||||
const payload = action.payload as unknown as ChangeViewStylePayload;
|
||||
const { style } = payload;
|
||||
const newState = state.withMutations(map => {
|
||||
map.setIn(['viewStyle'], style);
|
||||
@ -492,10 +491,8 @@ export function selectGroups(state: Entries, collection: Collection) {
|
||||
return [];
|
||||
}
|
||||
|
||||
let groups: Record<
|
||||
string,
|
||||
{ id: string; label: string; value: string | boolean | undefined }
|
||||
> = {};
|
||||
let groups: Record<string, { id: string; label: string; value: string | boolean | undefined }> =
|
||||
{};
|
||||
const groupedEntries = groupBy(entries.toArray(), entry => {
|
||||
const group = getGroup(entry, selectedGroup);
|
||||
groups = { ...groups, [group.id]: group };
|
||||
|
@ -262,7 +262,7 @@ export function selectMediaFileByPath(state: State, path: string) {
|
||||
export function selectMediaDisplayURL(state: State, id: string) {
|
||||
const displayUrlState = state.mediaLibrary.getIn(
|
||||
['displayURLs', id],
|
||||
(Map() as unknown) as DisplayURLState,
|
||||
Map() as unknown as DisplayURLState,
|
||||
);
|
||||
return displayUrlState;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import { State } from '../types/redux';
|
||||
import { Reducer } from 'react';
|
||||
|
||||
const store = createStore<State | undefined, AnyAction, unknown, unknown>(
|
||||
(createRootReducer() as unknown) as Reducer<State | undefined, AnyAction>,
|
||||
createRootReducer() as unknown as Reducer<State | undefined, AnyAction>,
|
||||
composeWithDevTools(applyMiddleware(thunkMiddleware as ThunkMiddleware<State>, waitUntilAction)),
|
||||
);
|
||||
|
||||
|
@ -51,13 +51,14 @@ export const waitUntilAction: Middleware<{}, State, Dispatch> = ({
|
||||
}
|
||||
}
|
||||
|
||||
return (next: Dispatch<AnyAction>) => (action: AnyAction): null | AnyAction => {
|
||||
if (action.type === WAIT_UNTIL_ACTION) {
|
||||
pending.push(action as WaitAction);
|
||||
return null;
|
||||
}
|
||||
const result = next(action);
|
||||
checkPending(action);
|
||||
return result;
|
||||
};
|
||||
return (next: Dispatch<AnyAction>) =>
|
||||
(action: AnyAction): null | AnyAction => {
|
||||
if (action.type === WAIT_UNTIL_ACTION) {
|
||||
pending.push(action as WaitAction);
|
||||
return null;
|
||||
}
|
||||
const result = next(action);
|
||||
checkPending(action);
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
@ -3,7 +3,7 @@ import { mocked } from 'ts-jest/utils';
|
||||
|
||||
jest.mock('history');
|
||||
|
||||
const history = ({ push: jest.fn(), replace: jest.fn() } as unknown) as History;
|
||||
const history = { push: jest.fn(), replace: jest.fn() } as unknown as History;
|
||||
const mockedCreateHashHistory = mocked(createHashHistory);
|
||||
mockedCreateHashHistory.mockReturnValue(history);
|
||||
|
||||
|
@ -11,7 +11,7 @@ export interface StaticallyTypedRecord<T> {
|
||||
K1 extends keyof T,
|
||||
K2 extends keyof T[K1],
|
||||
K3 extends keyof T[K1][K2],
|
||||
V extends T[K1][K2][K3]
|
||||
V extends T[K1][K2][K3],
|
||||
>(
|
||||
keys: [K1, K2, K3],
|
||||
defaultValue?: V,
|
||||
|
Reference in New Issue
Block a user