feat: content in sub folders (#2897)

This commit is contained in:
Erez Rokah
2019-11-28 05:39:33 +02:00
committed by Shawn Erquhart
parent 766ade1a3c
commit afcfe5b6d5
44 changed files with 7218 additions and 8225 deletions

View File

@ -155,6 +155,14 @@ export default class API {
return `${this.repo}/${collectionName}/${slug}`;
}
slugFromContentKey(contentKey, collectionName) {
if (!this.useOpenAuthoring) {
return contentKey.substring(collectionName.length + 1);
}
return contentKey.substring(this.repo.length + collectionName.length + 2);
}
generateBranchName(contentKey) {
return `${CMS_BRANCH_PREFIX}/${contentKey}`;
}
@ -365,7 +373,9 @@ export default class API {
listFiles(path, { repoURL = this.repoURL, branch = this.branch } = {}) {
const folderPath = path.replace(/\/$/, '');
return this.request(`${repoURL}/git/trees/${branch}:${folderPath}`).then(res =>
return this.request(`${repoURL}/git/trees/${branch}:${folderPath}`, {
params: { recursive: 10 },
}).then(res =>
res.tree
.filter(file => file.type === 'blob')
.map(file => ({
@ -448,8 +458,9 @@ export default class API {
const { state: currentState, merged_at: mergedAt } = originPRInfo;
if (currentState === 'closed' && mergedAt) {
// The PR has been merged; delete the unpublished entry
const [, collectionName, slug] = contentKey.split('/');
this.deleteUnpublishedEntry(collectionName, slug);
const { collection } = metadata;
const slug = this.slugFromContentKey(contentKey, collection);
this.deleteUnpublishedEntry(collection, slug);
return;
} else if (currentState === 'closed' && !mergedAt) {
if (status !== 'draft') {

View File

@ -186,6 +186,26 @@ export default class GraphQLAPI extends API {
}
}
getAllFiles(entries, path) {
const allFiles = entries.reduce((acc, item) => {
if (item.type === 'tree') {
return [...acc, ...this.getAllFiles(item.object.entries, `${path}/${item.name}`)];
} else if (item.type === 'blob') {
return [
...acc,
{
...item,
path: `${path}/${item.name}`,
size: item.blob && item.blob.size,
},
];
}
return acc;
}, []);
return allFiles;
}
async listFiles(path, { repoURL = this.repoURL, branch = this.branch } = {}) {
const { owner, name } = this.getOwnerAndNameFromRepoUrl(repoURL);
const { data } = await this.query({
@ -194,14 +214,8 @@ export default class GraphQLAPI extends API {
});
if (data.repository.object) {
const files = data.repository.object.entries
.filter(({ type }) => type === 'blob')
.map(e => ({
...e,
path: `${path}/${e.name}`,
size: e.blob && e.blob.size,
}));
return files;
const allFiles = this.getAllFiles(data.repository.object.entries, path);
return allFiles;
} else {
throw new APIError('Not Found', 404, 'GitHub');
}

View File

@ -0,0 +1,72 @@
import GraphQLAPI from '../GraphQLAPI';
global.fetch = jest.fn().mockRejectedValue(new Error('should not call fetch inside tests'));
describe('github GraphQL API', () => {
beforeEach(() => {
jest.resetAllMocks();
});
describe('editorialWorkflowGit', () => {
it('should should flatten nested tree into a list of files', () => {
const api = new GraphQLAPI({ branch: 'gh-pages', repo: 'my-repo' });
const entries = [
{
name: 'post-1.md',
sha: 'sha-1',
type: 'blob',
blob: { size: 1 },
},
{
name: 'post-2.md',
sha: 'sha-2',
type: 'blob',
blob: { size: 2 },
},
{
name: '2019',
sha: 'dir-sha',
type: 'tree',
object: {
entries: [
{
name: 'nested-post.md',
sha: 'nested-post-sha',
type: 'blob',
blob: { size: 3 },
},
],
},
},
];
const path = 'posts';
expect(api.getAllFiles(entries, path)).toEqual([
{
name: 'post-1.md',
sha: 'sha-1',
type: 'blob',
size: 1,
path: 'posts/post-1.md',
blob: { size: 1 },
},
{
name: 'post-2.md',
sha: 'sha-2',
type: 'blob',
size: 2,
path: 'posts/post-2.md',
blob: { size: 2 },
},
{
name: 'nested-post.md',
sha: 'nested-post-sha',
type: 'blob',
size: 3,
path: 'posts/2019/nested-post.md',
blob: { size: 3 },
},
]);
});
});
});

View File

@ -389,7 +389,6 @@ export default class GitHub {
promises.push(
new Promise(resolve => {
const contentKey = this.api.contentKeyFromRef(ref);
const slug = contentKey.split('/').pop();
return sem.take(() =>
this.api
.readUnpublishedBranchFile(contentKey)
@ -399,7 +398,7 @@ export default class GitHub {
sem.leave();
} else {
resolve({
slug,
slug: this.api.slugFromContentKey(contentKey, data.metaData.collection),
file: { path: data.metaData.objects.entry.path },
data: data.fileData,
metaData: data.metaData,

View File

@ -1,4 +1,5 @@
import gql from 'graphql-tag';
import { oneLine } from 'common-tags';
import * as fragments from './fragments';
export const repoPermission = gql`
@ -92,17 +93,47 @@ export const statues = gql`
${fragments.object}
`;
const buildFilesQuery = (depth = 10) => {
const PLACE_HOLDER = 'PLACE_HOLDER';
let query = oneLine`
...ObjectParts
... on Tree {
entries {
...FileEntryParts
${PLACE_HOLDER}
}
}
`;
for (let i = 0; i < depth - 1; i++) {
query = query.replace(
PLACE_HOLDER,
oneLine`
object {
... on Tree {
entries {
...FileEntryParts
${PLACE_HOLDER}
}
}
}
`,
);
}
query = query.replace(PLACE_HOLDER, '');
return query;
};
const filesQuery = buildFilesQuery();
export const files = gql`
query files($owner: String!, $name: String!, $expression: String!) {
repository(owner: $owner, name: $name) {
...RepositoryParts
object(expression: $expression) {
...ObjectParts
... on Tree {
entries {
...FileEntryParts
}
}
${filesQuery}
}
}
}