-
Notifications
You must be signed in to change notification settings - Fork 0
/
fetchers.js
116 lines (97 loc) · 3.49 KB
/
fetchers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Returns the name of the default branch of the given repo.
// undefined if repo doesn't exist or some error while fetching.
const getDefaultBranchName = async (owner, repo) => {
try {
const res = await fetch(`https://api.github.com/repos/${owner}/${repo}`);
const data = await res.json();
return data.default_branch;
} catch (err) {
console.log(err);
}
};
// Returns the tree_sha of a given branch.
const getBranchTreeSha = async (owner, repo, branch) => {
try {
const res = await fetch(
`https://api.github.com/repos/${owner}/${repo}/branches/${branch}`
);
const data = await res.json();
return data.commit.sha;
} catch (err) {
console.log(err);
}
};
// Tree here refers to the list of all the files and subdirs
// inside the directory corresponding to the given tree_sha.
// Since recursive is set to true, it will also expand all the subdirs.
const getTree = async (owner, repo, tree_sha) => {
try {
const res = await fetch(
`https://api.github.com/repos/${owner}/${repo}/git/trees/${tree_sha}?recursive=true`
);
const data = await res.json();
return data.tree;
} catch (err) {
console.log(err);
}
};
const canBeCompressed = (dir) => {
return dir.subDirs.length === 1 && dir.files.length === 0;
};
const compressDir = (dir) => {
if (!canBeCompressed(dir) || !dir.parent) return;
const subDir = dir.subDirs[0];
subDir.name = `${dir.name}/${subDir.name}`;
const ind = dir.parent.subDirs.indexOf(dir);
dir.parent.subDirs[ind] = subDir;
};
const recGetDirectoryTree = (contents, curDir, owner, repo, branch) => {
while (contents.length > 0) {
const content = contents.pop();
// All contents belong to the root directory
// So for all other directories check if that content belongs to that directory
if (curDir.path != "/" && !content.path.startsWith(`${curDir.path}/`)) {
contents.push(content);
break;
}
const name = content.path.split("/").pop();
if (content.type === "tree") {
const subDir = new Dir(name, content.path, curDir);
curDir.addSubDir(subDir);
recGetDirectoryTree(contents, subDir, owner, repo, branch);
} else {
const link = `https://github.com/${owner}/${repo}/blob/${branch}/${content.path}`;
const file = new File_(name, content.path, link);
curDir.addFile(file);
}
}
compressDir(curDir);
};
// Returns a tree corresponding to the directory structure.
const getDirectoryTree = async (owner, repo, branch) => {
try {
const tree_sha = await getBranchTreeSha(owner, repo, branch);
const contents = await getTree(owner, repo, tree_sha);
const root = new Dir("root", "/", undefined);
// Note: passing the reversed array because pop() is faster than shift()
recGetDirectoryTree(contents.reverse(), root, owner, repo, branch);
return root;
} catch (err) {
console.log(err);
}
};
// Returns the branch name of the current url.
// undefined if the url is not a repo or some error occurred.
const getBranchName = async (url, owner, repo) => {
try {
const res = await fetch(url);
if (!res.ok) return undefined;
const data = url.split("/");
if (data.length === 5) return await getDefaultBranchName(owner, repo);
if (data.length === 6) return undefined;
if (data[5] !== "blob" && data[5] !== "tree") return undefined;
return data[6];
} catch (err) {
console.log(err);
}
};