decap-cms-core
Version:
Decap CMS core application, see decap-cms package for the main distribution.
589 lines (587 loc) • 19.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.MEDIA_REMOVE_INSERTED = exports.MEDIA_PERSIST_SUCCESS = exports.MEDIA_PERSIST_REQUEST = exports.MEDIA_PERSIST_FAILURE = exports.MEDIA_LOAD_SUCCESS = exports.MEDIA_LOAD_REQUEST = exports.MEDIA_LOAD_FAILURE = exports.MEDIA_LIBRARY_OPEN = exports.MEDIA_LIBRARY_CREATE = exports.MEDIA_LIBRARY_CLOSE = exports.MEDIA_INSERT = exports.MEDIA_DISPLAY_URL_SUCCESS = exports.MEDIA_DISPLAY_URL_REQUEST = exports.MEDIA_DISPLAY_URL_FAILURE = exports.MEDIA_DELETE_SUCCESS = exports.MEDIA_DELETE_REQUEST = exports.MEDIA_DELETE_FAILURE = void 0;
exports.clearMediaControl = clearMediaControl;
exports.closeMediaLibrary = closeMediaLibrary;
exports.createMediaLibrary = createMediaLibrary;
exports.deleteMedia = deleteMedia;
exports.getMediaDisplayURL = getMediaDisplayURL;
exports.getMediaFile = getMediaFile;
exports.insertMedia = insertMedia;
exports.loadMedia = loadMedia;
exports.loadMediaDisplayURL = loadMediaDisplayURL;
exports.mediaDeleteFailed = mediaDeleteFailed;
exports.mediaDeleted = mediaDeleted;
exports.mediaDeleting = mediaDeleting;
exports.mediaDisplayURLFailure = mediaDisplayURLFailure;
exports.mediaDisplayURLRequest = mediaDisplayURLRequest;
exports.mediaDisplayURLSuccess = mediaDisplayURLSuccess;
exports.mediaLoadFailed = mediaLoadFailed;
exports.mediaLoaded = mediaLoaded;
exports.mediaLoading = mediaLoading;
exports.mediaPersistFailed = mediaPersistFailed;
exports.mediaPersisted = mediaPersisted;
exports.mediaPersisting = mediaPersisting;
exports.openMediaLibrary = openMediaLibrary;
exports.persistMedia = persistMedia;
exports.removeInsertedMedia = removeInsertedMedia;
exports.removeMediaControl = removeMediaControl;
exports.waitForMediaLibraryToLoad = waitForMediaLibraryToLoad;
var _immutable = require("immutable");
var _decapCmsLibUtil = require("decap-cms-lib-util");
var _backend = require("../backend");
var _AssetProxy = require("../valueObjects/AssetProxy");
var _reducers = require("../reducers");
var _entries = require("../reducers/entries");
var _mediaLibrary = require("../reducers/mediaLibrary");
var _integrations = require("../integrations");
var _media = require("./media");
var _entries2 = require("./entries");
var _urlHelper = require("../lib/urlHelper");
var _waitUntil = require("./waitUntil");
var _notifications = require("./notifications");
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
const MEDIA_LIBRARY_OPEN = exports.MEDIA_LIBRARY_OPEN = 'MEDIA_LIBRARY_OPEN';
const MEDIA_LIBRARY_CLOSE = exports.MEDIA_LIBRARY_CLOSE = 'MEDIA_LIBRARY_CLOSE';
const MEDIA_LIBRARY_CREATE = exports.MEDIA_LIBRARY_CREATE = 'MEDIA_LIBRARY_CREATE';
const MEDIA_INSERT = exports.MEDIA_INSERT = 'MEDIA_INSERT';
const MEDIA_REMOVE_INSERTED = exports.MEDIA_REMOVE_INSERTED = 'MEDIA_REMOVE_INSERTED';
const MEDIA_LOAD_REQUEST = exports.MEDIA_LOAD_REQUEST = 'MEDIA_LOAD_REQUEST';
const MEDIA_LOAD_SUCCESS = exports.MEDIA_LOAD_SUCCESS = 'MEDIA_LOAD_SUCCESS';
const MEDIA_LOAD_FAILURE = exports.MEDIA_LOAD_FAILURE = 'MEDIA_LOAD_FAILURE';
const MEDIA_PERSIST_REQUEST = exports.MEDIA_PERSIST_REQUEST = 'MEDIA_PERSIST_REQUEST';
const MEDIA_PERSIST_SUCCESS = exports.MEDIA_PERSIST_SUCCESS = 'MEDIA_PERSIST_SUCCESS';
const MEDIA_PERSIST_FAILURE = exports.MEDIA_PERSIST_FAILURE = 'MEDIA_PERSIST_FAILURE';
const MEDIA_DELETE_REQUEST = exports.MEDIA_DELETE_REQUEST = 'MEDIA_DELETE_REQUEST';
const MEDIA_DELETE_SUCCESS = exports.MEDIA_DELETE_SUCCESS = 'MEDIA_DELETE_SUCCESS';
const MEDIA_DELETE_FAILURE = exports.MEDIA_DELETE_FAILURE = 'MEDIA_DELETE_FAILURE';
const MEDIA_DISPLAY_URL_REQUEST = exports.MEDIA_DISPLAY_URL_REQUEST = 'MEDIA_DISPLAY_URL_REQUEST';
const MEDIA_DISPLAY_URL_SUCCESS = exports.MEDIA_DISPLAY_URL_SUCCESS = 'MEDIA_DISPLAY_URL_SUCCESS';
const MEDIA_DISPLAY_URL_FAILURE = exports.MEDIA_DISPLAY_URL_FAILURE = 'MEDIA_DISPLAY_URL_FAILURE';
function createMediaLibrary(instance) {
const api = {
show: instance.show || (() => undefined),
hide: instance.hide || (() => undefined),
onClearControl: instance.onClearControl || (() => undefined),
onRemoveControl: instance.onRemoveControl || (() => undefined),
enableStandalone: instance.enableStandalone || (() => undefined)
};
return {
type: MEDIA_LIBRARY_CREATE,
payload: api
};
}
function clearMediaControl(id) {
return (_dispatch, getState) => {
const state = getState();
const mediaLibrary = state.mediaLibrary.get('externalLibrary');
if (mediaLibrary) {
mediaLibrary.onClearControl({
id
});
}
};
}
function removeMediaControl(id) {
return (_dispatch, getState) => {
const state = getState();
const mediaLibrary = state.mediaLibrary.get('externalLibrary');
if (mediaLibrary) {
mediaLibrary.onRemoveControl({
id
});
}
};
}
function openMediaLibrary(payload = {}) {
return (dispatch, getState) => {
const state = getState();
const mediaLibrary = state.mediaLibrary.get('externalLibrary');
if (mediaLibrary) {
const {
controlID: id,
value,
config = (0, _immutable.Map)(),
allowMultiple,
forImage
} = payload;
mediaLibrary.show({
id,
value,
config: config.toJS(),
allowMultiple,
imagesOnly: forImage
});
}
dispatch(mediaLibraryOpened(payload));
};
}
function closeMediaLibrary() {
return (dispatch, getState) => {
const state = getState();
const mediaLibrary = state.mediaLibrary.get('externalLibrary');
if (mediaLibrary) {
mediaLibrary.hide();
}
dispatch(mediaLibraryClosed());
};
}
function insertMedia(mediaPath, field) {
return (dispatch, getState) => {
const state = getState();
const config = state.config;
const entry = state.entryDraft.get('entry');
const collectionName = state.entryDraft.getIn(['entry', 'collection']);
const collection = state.collections.get(collectionName);
if (Array.isArray(mediaPath)) {
mediaPath = mediaPath.map(path => (0, _entries.selectMediaFilePublicPath)(config, collection, path, entry, field));
} else {
mediaPath = (0, _entries.selectMediaFilePublicPath)(config, collection, mediaPath, entry, field);
}
dispatch(mediaInserted(mediaPath));
};
}
function removeInsertedMedia(controlID) {
return {
type: MEDIA_REMOVE_INSERTED,
payload: {
controlID
}
};
}
function loadMedia(opts = {}) {
const {
delay = 0,
query = '',
page = 1,
privateUpload
} = opts;
return async (dispatch, getState) => {
const state = getState();
const backend = (0, _backend.currentBackend)(state.config);
const integration = (0, _reducers.selectIntegration)(state, null, 'assetStore');
if (integration) {
const provider = (0, _integrations.getIntegrationProvider)(state.integrations, backend.getToken, integration);
dispatch(mediaLoading(page));
try {
const files = await provider.retrieve(query, page, privateUpload);
const mediaLoadedOpts = {
page,
canPaginate: true,
dynamicSearch: true,
dynamicSearchQuery: query,
privateUpload
};
return dispatch(mediaLoaded(files, mediaLoadedOpts));
} catch (error) {
return dispatch(mediaLoadFailed({
privateUpload
}));
}
}
dispatch(mediaLoading(page));
function loadFunction() {
return backend.getMedia().then(files => dispatch(mediaLoaded(files))).catch(error => {
console.error(error);
if (error.status === 404) {
console.log('This 404 was expected and handled appropriately.');
dispatch(mediaLoaded([]));
} else {
dispatch(mediaLoadFailed());
}
});
}
if (delay > 0) {
return new Promise(resolve => {
setTimeout(() => resolve(loadFunction()), delay);
});
} else {
return loadFunction();
}
};
}
function createMediaFileFromAsset({
id,
file,
assetProxy,
draft
}) {
const mediaFile = {
id,
name: (0, _decapCmsLibUtil.basename)(assetProxy.path),
displayURL: assetProxy.url,
draft,
file,
size: file.size,
url: assetProxy.url,
path: assetProxy.path,
field: assetProxy.field
};
return mediaFile;
}
function persistMedia(file, opts = {}) {
const {
privateUpload,
field
} = opts;
return async (dispatch, getState) => {
const state = getState();
const backend = (0, _backend.currentBackend)(state.config);
const integration = (0, _reducers.selectIntegration)(state, null, 'assetStore');
const files = (0, _mediaLibrary.selectMediaFiles)(state, field);
const fileName = (0, _urlHelper.sanitizeSlug)(file.name.toLowerCase(), state.config.slug);
const existingFile = files.find(existingFile => existingFile.name.toLowerCase() === fileName);
const editingDraft = (0, _entries.selectEditingDraft)(state.entryDraft);
/**
* Check for existing files of the same name before persisting. If no asset
* store integration is used, files are being stored in Git, so we can
* expect file names to be unique. If an asset store is in use, file names
* may not be unique, so we forego this check.
*/
if (!integration && existingFile) {
if (!window.confirm(`${existingFile.name} already exists. Do you want to replace it?`)) {
return;
} else {
await dispatch(deleteMedia(existingFile, {
privateUpload
}));
}
}
if (integration || !editingDraft) {
dispatch(mediaPersisting());
}
try {
let assetProxy;
if (integration) {
try {
const provider = (0, _integrations.getIntegrationProvider)(state.integrations, backend.getToken, integration);
const response = await provider.upload(file, privateUpload);
assetProxy = (0, _AssetProxy.createAssetProxy)({
url: response.asset.url,
path: response.asset.url
});
} catch (error) {
assetProxy = (0, _AssetProxy.createAssetProxy)({
file,
path: fileName
});
}
} else if (privateUpload) {
throw new Error('The Private Upload option is only available for Asset Store Integration');
} else {
const entry = state.entryDraft.get('entry');
const collection = state.collections.get(entry === null || entry === void 0 ? void 0 : entry.get('collection'));
const path = (0, _entries.selectMediaFilePath)(state.config, collection, entry, fileName, field);
assetProxy = (0, _AssetProxy.createAssetProxy)({
file,
path,
field
});
}
dispatch((0, _media.addAsset)(assetProxy));
let mediaFile;
if (integration) {
const id = await (0, _decapCmsLibUtil.getBlobSHA)(file);
// integration assets are persisted immediately, thus draft is false
mediaFile = createMediaFileFromAsset({
id,
file,
assetProxy,
draft: false
});
} else if (editingDraft) {
const id = await (0, _decapCmsLibUtil.getBlobSHA)(file);
mediaFile = createMediaFileFromAsset({
id,
file,
assetProxy,
draft: editingDraft
});
return dispatch((0, _entries2.addDraftEntryMediaFile)(mediaFile));
} else {
mediaFile = await backend.persistMedia(state.config, assetProxy);
}
return dispatch(mediaPersisted(mediaFile, {
privateUpload
}));
} catch (error) {
console.error(error);
dispatch((0, _notifications.addNotification)({
message: `Failed to persist media: ${error}`,
type: 'error',
dismissAfter: 8000
}));
return dispatch(mediaPersistFailed({
privateUpload
}));
}
};
}
function deleteMedia(file, opts = {}) {
const {
privateUpload
} = opts;
return async (dispatch, getState) => {
const state = getState();
const backend = (0, _backend.currentBackend)(state.config);
const integration = (0, _reducers.selectIntegration)(state, null, 'assetStore');
if (integration) {
const provider = (0, _integrations.getIntegrationProvider)(state.integrations, backend.getToken, integration);
dispatch(mediaDeleting());
try {
await provider.delete(file.id);
return dispatch(mediaDeleted(file, {
privateUpload
}));
} catch (error) {
console.error(error);
dispatch((0, _notifications.addNotification)({
message: `Failed to delete media: ${error.message}`,
type: 'error',
dismissAfter: 8000
}));
return dispatch(mediaDeleteFailed({
privateUpload
}));
}
}
try {
if (file.draft) {
dispatch((0, _media.removeAsset)(file.path));
dispatch((0, _entries2.removeDraftEntryMediaFile)({
id: file.id
}));
} else {
const editingDraft = (0, _entries.selectEditingDraft)(state.entryDraft);
dispatch(mediaDeleting());
dispatch((0, _media.removeAsset)(file.path));
await backend.deleteMedia(state.config, file.path);
dispatch(mediaDeleted(file));
if (editingDraft) {
dispatch((0, _entries2.removeDraftEntryMediaFile)({
id: file.id
}));
}
}
} catch (error) {
console.error(error);
dispatch((0, _notifications.addNotification)({
message: `Failed to delete media: ${error.message}`,
type: 'error',
dismissAfter: 8000
}));
return dispatch(mediaDeleteFailed());
}
};
}
async function getMediaFile(state, path) {
const backend = (0, _backend.currentBackend)(state.config);
const {
url
} = await backend.getMediaFile(path);
return {
url
};
}
function loadMediaDisplayURL(file) {
return async (dispatch, getState) => {
const {
displayURL,
id
} = file;
const state = getState();
const displayURLState = (0, _mediaLibrary.selectMediaDisplayURL)(state, id);
if (!id || !displayURL || displayURLState.get('url') || displayURLState.get('isFetching') || displayURLState.get('err')) {
return Promise.resolve();
}
if (typeof displayURL === 'string') {
dispatch(mediaDisplayURLRequest(id));
dispatch(mediaDisplayURLSuccess(id, displayURL));
return;
}
try {
const backend = (0, _backend.currentBackend)(state.config);
dispatch(mediaDisplayURLRequest(id));
const newURL = await backend.getMediaDisplayURL(displayURL);
if (newURL) {
dispatch(mediaDisplayURLSuccess(id, newURL));
} else {
throw new Error('No display URL was returned!');
}
} catch (err) {
console.error(err);
dispatch(mediaDisplayURLFailure(id, err));
}
};
}
function mediaLibraryOpened(payload) {
return {
type: MEDIA_LIBRARY_OPEN,
payload
};
}
function mediaLibraryClosed() {
return {
type: MEDIA_LIBRARY_CLOSE
};
}
function mediaInserted(mediaPath) {
return {
type: MEDIA_INSERT,
payload: {
mediaPath
}
};
}
function mediaLoading(page) {
return {
type: MEDIA_LOAD_REQUEST,
payload: {
page
}
};
}
function mediaLoaded(files, opts = {}) {
return {
type: MEDIA_LOAD_SUCCESS,
payload: _objectSpread({
files
}, opts)
};
}
function mediaLoadFailed(opts = {}) {
const {
privateUpload
} = opts;
return {
type: MEDIA_LOAD_FAILURE,
payload: {
privateUpload
}
};
}
function mediaPersisting() {
return {
type: MEDIA_PERSIST_REQUEST
};
}
function mediaPersisted(file, opts = {}) {
const {
privateUpload
} = opts;
return {
type: MEDIA_PERSIST_SUCCESS,
payload: {
file,
privateUpload
}
};
}
function mediaPersistFailed(opts = {}) {
const {
privateUpload
} = opts;
return {
type: MEDIA_PERSIST_FAILURE,
payload: {
privateUpload
}
};
}
function mediaDeleting() {
return {
type: MEDIA_DELETE_REQUEST
};
}
function mediaDeleted(file, opts = {}) {
const {
privateUpload
} = opts;
return {
type: MEDIA_DELETE_SUCCESS,
payload: {
file,
privateUpload
}
};
}
function mediaDeleteFailed(opts = {}) {
const {
privateUpload
} = opts;
return {
type: MEDIA_DELETE_FAILURE,
payload: {
privateUpload
}
};
}
function mediaDisplayURLRequest(key) {
return {
type: MEDIA_DISPLAY_URL_REQUEST,
payload: {
key
}
};
}
function mediaDisplayURLSuccess(key, url) {
return {
type: MEDIA_DISPLAY_URL_SUCCESS,
payload: {
key,
url
}
};
}
function mediaDisplayURLFailure(key, err) {
return {
type: MEDIA_DISPLAY_URL_FAILURE,
payload: {
key,
err
}
};
}
async function waitForMediaLibraryToLoad(dispatch, state) {
if (state.mediaLibrary.get('isLoading') !== false && !state.mediaLibrary.get('externalLibrary')) {
await (0, _waitUntil.waitUntilWithTimeout)(dispatch, resolve => ({
predicate: ({
type
}) => type === MEDIA_LOAD_SUCCESS || type === MEDIA_LOAD_FAILURE,
run: () => resolve()
}));
}
}
async function getMediaDisplayURL(dispatch, state, file) {
const displayURLState = (0, _mediaLibrary.selectMediaDisplayURL)(state, file.id);
let url;
if (displayURLState.get('url')) {
// url was already loaded
url = displayURLState.get('url');
} else if (displayURLState.get('err')) {
// url loading had an error
url = null;
} else {
var _await$promise;
const key = file.id;
const promise = (0, _waitUntil.waitUntilWithTimeout)(dispatch, resolve => ({
predicate: ({
type,
payload
}) => (type === MEDIA_DISPLAY_URL_SUCCESS || type === MEDIA_DISPLAY_URL_FAILURE) && payload.key === key,
run: (_dispatch, _getState, action) => resolve(action.payload.url)
}));
if (!displayURLState.get('isFetching')) {
// load display url
dispatch(loadMediaDisplayURL(file));
}
url = (_await$promise = await promise) !== null && _await$promise !== void 0 ? _await$promise : null;
}
return url;
}