feat: bundle assets with content (#2958)

* fix(media_folder_relative): use collection name in unpublished entry

* refactor: pass arguments as object to AssetProxy ctor

* feat: support media folders per collection

* feat: resolve media files path based on entry path

* fix: asset public path resolving

* refactor: introduce typescript for AssetProxy

* refactor: code cleanup

* refactor(asset-proxy): add tests,switch to typescript,extract arguments

* refactor: typescript for editorialWorkflow

* refactor: add typescript for media library actions

* refactor: fix type error on map set

* refactor: move locale selector into reducer

* refactor: add typescript for entries actions

* refactor: remove duplication between asset store and media lib

* feat: load assets from backend using API

* refactor(github): add typescript, cache media files

* fix: don't load media URL if already loaded

* feat: add media folder config to collection

* fix: load assets from API when not in UI state

* feat: load entry media files when opening media library

* fix: editorial workflow draft media files bug fixes

* test(unit): fix unit tests

* fix: editor control losing focus

* style: add eslint object-shorthand rule

* test(cypress): re-record mock data

* fix: fix non github backends, large media

* test: uncomment only in tests

* fix(backend-test): add missing displayURL property

* test(e2e): add media library tests

* test(e2e): enable visual testing

* test(e2e): add github backend media library tests

* test(e2e): add git-gateway large media tests

* chore: post rebase fixes

* test: fix tests

* test: fix tests

* test(cypress): fix tests

* docs: add media_folder docs

* test(e2e): add media library delete test

* test(e2e): try and fix image comparison on CI

* ci: reduce test machines from 9 to 8

* test: add reducers and selectors unit tests

* test(e2e): disable visual regression testing for now

* test: add getAsset unit tests

* refactor: use Asset class component instead of hooks

* build: don't inline source maps

* test: add more media path tests
This commit is contained in:
Erez Rokah
2019-12-18 18:16:02 +02:00
committed by Shawn Erquhart
parent 7e4d4c1cc4
commit 2b41d8a838
231 changed files with 37961 additions and 18373 deletions

View File

@ -45,7 +45,7 @@ export default class API extends GithubAPI {
return this.tokenPromise().then(jwtToken => {
const baseHeader = {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
'Content-Type': 'application/json; charset=utf-8',
...headers,
};

View File

@ -30,7 +30,10 @@ describe('github API', () => {
expect(fetch).toHaveBeenCalledWith(
'https://site.netlify.com/.netlify/git/github/some-path?ts=1000',
{
headers: { Authorization: 'Bearer token', 'Content-Type': 'application/json' },
headers: {
Authorization: 'Bearer token',
'Content-Type': 'application/json; charset=utf-8',
},
},
);
});

View File

@ -2,7 +2,7 @@ import GoTrue from 'gotrue-js';
import jwtDecode from 'jwt-decode';
import { fromPairs, get, pick, intersection, unzip } from 'lodash';
import ini from 'ini';
import { APIError, getBlobSHA, unsentRequest } from 'netlify-cms-lib-util';
import { APIError, getBlobSHA, unsentRequest, basename } from 'netlify-cms-lib-util';
import { GitHubBackend } from 'netlify-cms-backend-github';
import { GitLabBackend } from 'netlify-cms-backend-gitlab';
import { BitbucketBackend, API as BitBucketAPI } from 'netlify-cms-backend-bitbucket';
@ -209,8 +209,37 @@ export default class GitGateway {
return this.backend.getEntry(collection, slug, path);
}
getMedia() {
return Promise.all([this.backend.getMedia(), this.getLargeMediaClient()]).then(
async loadEntryMediaFiles(files) {
const client = await this.getLargeMediaClient();
if (!client.enabled) {
return this.backend.loadEntryMediaFiles(files);
}
const mediaFiles = await Promise.all(
files.map(async file => {
if (client.matchPath(file.path)) {
const { sha: id, path } = file;
const largeMediaDisplayURLs = await this.getLargeMediaDisplayURLs([{ ...file, id }]);
const url = await client.getDownloadURL(largeMediaDisplayURLs[id]);
return {
...file,
id,
name: basename(path),
path,
url,
displayURL: url,
};
} else {
return this.backend.loadMediaFile(file);
}
}),
);
return mediaFiles;
}
getMedia(mediaFolder = this.config.get('media_folder')) {
return Promise.all([this.backend.getMedia(mediaFolder), this.getLargeMediaClient()]).then(
async ([mediaFiles, largeMediaClient]) => {
if (!largeMediaClient.enabled) {
return mediaFiles.map(({ displayURL, ...rest }) => ({
@ -218,6 +247,9 @@ export default class GitGateway {
displayURL: { original: displayURL },
}));
}
if (mediaFiles.length === 0) {
return [];
}
const largeMediaDisplayURLs = await this.getLargeMediaDisplayURLs(mediaFiles);
return mediaFiles.map(({ id, displayURL, path, ...rest }) => {
return {
@ -339,6 +371,21 @@ export default class GitGateway {
});
}
async getMediaFile(path) {
const client = await this.getLargeMediaClient();
if (client.enabled && client.matchPath(path)) {
const largeMediaDisplayURLs = await this.getLargeMediaDisplayURLs([{ path }]);
const url = await client.getDownloadURL(Object.values(largeMediaDisplayURLs)[0]);
return {
name: basename(path),
path,
url,
displayURL: url,
};
}
return this.backend.getMediaFile(path);
}
async getPointerFileForMediaFileObj(fileObj) {
const client = await this.getLargeMediaClient();
const { name, size } = fileObj;
@ -419,10 +466,13 @@ export default class GitGateway {
return this.backend.unpublishedEntries();
}
unpublishedEntry(collection, slug) {
return (
(this.backend.unpublishedEntry && this.backend.unpublishedEntry(collection, slug)) ||
Promise.resolve(false)
);
if (!this.backend.unpublishedEntry) {
return Promise.resolve(false);
}
return this.backend.unpublishedEntry(collection, slug, {
loadEntryMediaFiles: files => this.loadEntryMediaFiles(files),
});
}
updateUnpublishedEntryStatus(collection, slug, newStatus) {
return this.backend.updateUnpublishedEntryStatus(collection, slug, newStatus);