aboutsummaryrefslogtreecommitdiff
path: root/packages/server/src/api/v1
diff options
context:
space:
mode:
Diffstat (limited to 'packages/server/src/api/v1')
-rw-r--r--packages/server/src/api/v1/index.ts59
-rw-r--r--packages/server/src/api/v1/repo/branches.ts33
-rw-r--r--packages/server/src/api/v1/repo/index.ts79
-rw-r--r--packages/server/src/api/v1/repo/log.ts64
4 files changed, 178 insertions, 57 deletions
diff --git a/packages/server/src/api/v1/index.ts b/packages/server/src/api/v1/index.ts
index 00652a8..a6ab918 100644
--- a/packages/server/src/api/v1/index.ts
+++ b/packages/server/src/api/v1/index.ts
@@ -1,12 +1,10 @@
import { FastifyInstance, FastifyPluginOptions } from "fastify";
-import { GitAPI } from "../git";
+import { Repository } from "../../git/repository";
import { Route } from "../../fastify_types";
import repo from "./repo";
import { verifyRepoName } from "../util";
-export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, done: (err?: Error) => void): void {
- const git = new GitAPI(opts.config.settings.base_dir);
-
+function setHandlers(fastify: FastifyInstance): void {
fastify.setErrorHandler((err, req, reply) => {
console.log(err);
reply.code(500).send({ error: "Internal server error!" });
@@ -14,21 +12,29 @@ export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, do
fastify.setNotFoundHandler((req, reply) => {
reply.code(404).send({ error: "Endpoint not found!" });
});
+}
- fastify.route({
- method: "GET",
- url: "/info",
- handler: (req, reply) => {
- reply.send({ data: { title: opts.config.settings.title, about: opts.config.settings.about } });
- }
- });
+function reposEndpoints(fastify: FastifyInstance, opts: FastifyPluginOptions, done: (err?: Error) => void): void {
fastify.route({
method: "GET",
url: "/repos",
handler: async(req, reply) => {
- const repos = await git.getRepositories();
+ const repos = await Repository.openAll(opts.config.settings.base_dir);
+
+ if(!repos) {
+ reply.send({ data: [] });
+ return;
+ }
- reply.send({ data: repos });
+ reply.send({
+ data: await Promise.all(repos.map(async repository => {
+ return {
+ name: repository.name.short,
+ description: repository.description,
+ last_updated: (await repository.latestCommit()).date
+ };
+ }))
+ });
}
});
@@ -39,15 +45,36 @@ export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, do
const repo_verification = await verifyRepoName(opts.config.settings.base_dir, req.params.repo);
if(repo_verification.success === false && repo_verification.code) {
reply.code(repo_verification.code).send({ error: repo_verification.message });
+ return;
}
- const desc = await git.getRepositoryFile(req.params.repo, "description");
+ const repository = await Repository.open(opts.config.settings.base_dir, req.params.repo);
- reply.send({ data: { name: req.params.repo, description: desc, has_readme: await git.doesReadmeExist(req.params.repo) } });
+ reply.send({
+ data: {
+ name: repository.name.short,
+ description: repository.description,
+ has_readme: await (await repository.tree()).findExists("README.md")
+ }
+ });
+ }
+ });
+ done();
+}
+
+export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, done: (err?: Error) => void): void {
+ setHandlers(fastify);
+
+ fastify.route({
+ method: "GET",
+ url: "/info",
+ handler: (req, reply) => {
+ reply.send({ data: { title: opts.config.settings.title, about: opts.config.settings.about } });
}
});
- fastify.register(repo, { prefix: "/repos/:repo", config: { git: git, settings: opts.config.settings } });
+ fastify.register(reposEndpoints, { config: { settings: opts.config.settings } });
+ fastify.register(repo, { prefix: "/repos/:repo", config: { settings: opts.config.settings } });
done();
} \ No newline at end of file
diff --git a/packages/server/src/api/v1/repo/branches.ts b/packages/server/src/api/v1/repo/branches.ts
index fd8056a..fe962aa 100644
--- a/packages/server/src/api/v1/repo/branches.ts
+++ b/packages/server/src/api/v1/repo/branches.ts
@@ -1,18 +1,22 @@
import { FastifyInstance, FastifyPluginOptions } from "fastify";
-import { GitAPI } from "../../git";
+import { Branch } from "../../../git/branch";
import { Route } from "../../../fastify_types";
-import { verifySHA } from "../../util";
export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, done: (err?: Error) => void): void {
- const git: GitAPI = opts.config.git;
-
fastify.route<Route>({
method: "GET",
url: "/branches",
handler: async(req, reply) => {
- const branches = await git.getBranches(req.params.repo);
-
- reply.send({ data: branches });
+ const branches = await (await req.repository).branches();
+
+ reply.send({
+ data: branches.map(branch => {
+ return {
+ id: branch.id,
+ name: branch.name
+ };
+ })
+ });
}
});
@@ -20,19 +24,20 @@ export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, do
method: "GET",
url: "/branches/:branch",
handler: async(req, reply) => {
- const branch_verification = await verifySHA(git, req.params.repo, req.params.branch);
- if(branch_verification.success === false && branch_verification.code) {
- reply.code(branch_verification.code).send({ error: branch_verification.message });
- }
-
- const branch = await git.getBranch(req.params.repo, req.params.branch);
+ const branch = await Branch.lookup(await req.repository, req.params.branch);
if(!branch) {
reply.code(404).send({ error: "Branch not found!" });
return;
}
- reply.send({ data: branch });
+ reply.send({
+ data: {
+ id: branch.id,
+ name: branch.name,
+ latest_commit: await branch.latestCommit()
+ }
+ });
}
});
diff --git a/packages/server/src/api/v1/repo/index.ts b/packages/server/src/api/v1/repo/index.ts
index 86e5d10..c13e173 100644
--- a/packages/server/src/api/v1/repo/index.ts
+++ b/packages/server/src/api/v1/repo/index.ts
@@ -1,37 +1,86 @@
-import { FastifyInstance, FastifyPluginOptions, FastifyRequest } from "fastify";
-import { GitAPI } from "../../git";
-import { Route } from "../../../fastify_types";
+import { CoolFastifyRequest, Route } from "../../../fastify_types";
+import { FastifyInstance, FastifyPluginOptions } from "fastify";
+import { Blob } from "../../../git/blob";
+import { Repository } from "../../../git/repository";
+import { Tag } from "../../../git/tag";
+import { TreeEntry } from "../../../git/tree_entry";
import branches from "./branches";
import log from "./log";
import { verifyRepoName } from "../../util";
-export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, done: (err?: Error) => void): void {
- const git: GitAPI = opts.config.git;
+declare module "fastify" {
+ interface FastifyRequest {
+ repository: Promise<Repository>,
+ }
+}
+
+function addHooks(fastify: FastifyInstance, opts: FastifyPluginOptions): void {
+ fastify.addHook("preHandler", (req: CoolFastifyRequest, reply, hookDone) => {
+ req.repository = Repository.open(opts.config.settings.base_dir, req.params.repo);
+
+ hookDone();
+ });
- fastify.addHook("onRequest", async(req: FastifyRequest<Route>, reply) => {
+ fastify.addHook("onRequest", async(req: CoolFastifyRequest, reply) => {
const repo_verification = await verifyRepoName(opts.config.settings.base_dir, req.params.repo);
if(repo_verification.success === false && repo_verification.code) {
reply.code(repo_verification.code).send({ error: repo_verification.message });
}
+
});
+}
+async function treeEntryMap(entry: TreeEntry) {
+ const latest_commit = await entry.latestCommit();
+ return {
+ path: entry.path,
+ latest_commit: {
+ id: latest_commit.id,
+ message: latest_commit.message,
+ date: latest_commit.date
+ }
+ };
+}
- fastify.register(log, { config: { git: git } });
- fastify.register(branches, { config: { git: git } });
+async function tagMap(tag: Tag) {
+ const author = await tag.author();
+ return {
+ name: tag.name,
+ author: { name: author.name, email: author.email },
+ date: await tag.date()
+ };
+}
+
+export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, done: (err?: Error) => void): void {
+ addHooks(fastify, opts);
+
+ fastify.register(log);
+ fastify.register(branches);
fastify.route<Route>({
method: "GET",
url: "/tree",
handler: async(req, reply) => {
+ const tree = await (await req.repository).tree();
+
const tree_path = (Object.keys(req.query).length !== 0 && req.query.path) ? req.query.path : null;
+ if(tree_path) {
+ const tree_found = await tree.find(tree_path);
+
+ if(!tree_found) {
+ reply.code(404).send({ error: "Tree path not found!" });
+ return;
+ }
- const tree = await git.getTree(req.params.repo, tree_path);
+ reply.send({
+ data: tree_found instanceof Blob
+ ? { type: "blob", content: await tree_found.content() }
+ : { type: "tree", content: await Promise.all(tree_found.entries().map(treeEntryMap)) }
+ });
- if(!tree) {
- reply.code(404).send({ error: "Path not found" });
return;
}
- reply.send({ data: tree });
+ reply.send({ data: await Promise.all(tree.entries().map(treeEntryMap)) });
}
});
@@ -39,8 +88,10 @@ export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, do
method: "GET",
url: "/tags",
handler: async(req, reply) => {
- const refs = await git.getTags(req.params.repo);
- reply.send({ data: refs });
+ const tags = await (await req.repository).tags();
+ reply.send({
+ data: await Promise.all(tags.map(tagMap))
+ });
}
});
diff --git a/packages/server/src/api/v1/repo/log.ts b/packages/server/src/api/v1/repo/log.ts
index f692b00..d21cfa8 100644
--- a/packages/server/src/api/v1/repo/log.ts
+++ b/packages/server/src/api/v1/repo/log.ts
@@ -1,23 +1,46 @@
import { FastifyInstance, FastifyPluginOptions } from "fastify";
-import { GitAPI } from "../../git";
+import { Commit } from "../../../git/commit";
+import { Patch } from "../../../git/patch";
import { Route } from "../../../fastify_types";
import { verifySHA } from "../../util";
-export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, done: (err?: Error) => void): void {
- const git: GitAPI = opts.config.git;
+async function commitMap(commit: Commit) {
+ const stats = await commit.stats();
+ return {
+ id: commit.id,
+ author: {
+ name: commit.author.name,
+ email: commit.author.email
+ },
+ message: commit.message,
+ date: commit.date,
+ insertions: stats.insertions,
+ deletions: stats.deletions,
+ files_changed: stats.files_changed
+ };
+}
+
+async function patchMap(patch: Patch) {
+ return {
+ additions: patch.additions,
+ deletions: patch.deletions,
+ from: patch.from,
+ to: patch.to,
+ too_large: patch.too_large,
+ hunks: await patch.getHunks()
+ };
+}
+export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, done: (err?: Error) => void): void {
fastify.route<Route>({
method: "GET",
url: "/log",
handler: async(req, reply) => {
- const log = await git.getLog(req.params.repo);
+ const commits = (await (await req.repository).commits());
- if(log.length === 0) {
- reply.code(500).send({ error: "Internal server error!" });
- return;
- }
-
- reply.send({ data: log });
+ reply.send({
+ data: await Promise.all(commits.map(commitMap))
+ });
}
});
@@ -25,14 +48,29 @@ export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, do
method: "GET",
url: "/log/:commit",
handler: async(req, reply) => {
- const commit_verification = await verifySHA(git, req.params.repo, req.params.commit);
+ const commit_verification = await verifySHA(await req.repository, req.params.commit);
if(commit_verification.success === false && commit_verification.code) {
reply.code(commit_verification.code).send({ error: commit_verification.message });
}
- const commit = await git.getCommit(req.params.repo, req.params.commit);
+ const commit = await Commit.lookup(await req.repository, req.params.commit);
+
+ const stats = await commit.stats();
- reply.send({ data: commit });
+ reply.send({
+ data: {
+ message: commit.message,
+ author: {
+ name: commit.author.name,
+ email: commit.author.email
+ },
+ date: commit.date,
+ insertions: stats.insertions,
+ deletions: stats.deletions,
+ files_changed: stats.files_changed,
+ diff: await Promise.all((await (await commit.diff()).getPatches()).map(patchMap))
+ }
+ });
}
});