Skip to content

Commit

Permalink
[#2] feat: 레포 디렉토리 구조
Browse files Browse the repository at this point in the history
  • Loading branch information
coolsmart2 committed Apr 3, 2023
1 parent 077117c commit 938020e
Show file tree
Hide file tree
Showing 15 changed files with 916 additions and 342 deletions.
2 changes: 1 addition & 1 deletion server/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import express, { Request, Response } from 'express';
import logger from 'morgan';
import githubRouter from './routes/github.route';
import githubRouter from './route/github.route';
import dotonv from 'dotenv';

dotonv.config();
Expand Down
62 changes: 62 additions & 0 deletions server/src/constant/error/octokit.error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* 찾는 파일이 없는 경우
*/
export class NotFoundError extends Error {
constructor() {
super('Not Found');
}
}

/**
* 같은 이름의 레포지토리가 있는 경우
*/
export class RepositoryCreationFailedError extends Error {
constructor() {
super('RepositoryCreationFailedError');
}
}

/**
* 깃허브 토큰이 입력이 안된 경우
*/
export class RequiresAuthenticationError extends Error {
constructor() {
super('RequiresAuthenticationError');
}
}

/**
* 깃허브 토큰이 인증이 안될 경우
*/
export class BadCredentialsError extends Error {
constructor() {
super('BadCredentialsError');
}
}

/**
* 중복된 브랜치를 만들 경우
*/
export class ReferenceAlreadyExistsError extends Error {
constructor() {
super('ReferenceAlreadyExistsError');
}
}

/**
* 브랜치가 없는 경우
*/
export class ReferenceDoesNotExistError extends Error {
constructor() {
super('ReferenceDoesNotExistError');
}
}

/**
* 레포지토리가 비어있는 경우 (새로 생성된 레포지토리 등)
*/
export class RepositoryIsEmptyError extends Error {
constructor() {
super('RepositoryIsEmptyError');
}
}
13 changes: 13 additions & 0 deletions server/src/constant/error/octokit.message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const NOT_FOUND = 'Not Found';

export const REPOSITORY_CREATION_FAILED = 'Repository creation failed';

export const REQUIRES_AUTHENTICATION = 'Requires authentication';

export const BAD_CREDENTIALS = 'Bad credentials';

export const REFERENCE_ALREADY_EXISTS = 'Reference already exists';

export const REFERENCE_DOES_NOT_EXIST = 'Reference does not exist';

export const REPOSITORY_IS_EMPTY = 'This repository is empty.';
41 changes: 0 additions & 41 deletions server/src/constants/errors/octokit.error.ts

This file was deleted.

222 changes: 222 additions & 0 deletions server/src/controller/github.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
import { Request, Response } from 'express';
import { Octokit } from '@octokit/rest';
import { findById } from '../service/user.service';
import {
addBranch,
addContent,
addRepo,
deleteBranch,
deleteRepo,
findAllRepo,
findContent,
findRepo,
modifyContent,
} from '../service/github.service';

/**
* completed
*/
export const githubRepoList = async (req: Request, res: Response) => {
const { token } = findById(1);

if (!token) return res.status(404).send([]);

try {
const repos = await findAllRepo(token);
return res.send(repos);
} catch (error) {
return res.status(500).send([]);
}
};

export const githubRepo = async (req: Request, res: Response) => {
const { repo: repoName } = req.params;
const { username, token } = findById(1);

if (!username || !token) return res.status(404).send([]);

try {
const repoStructure = await findRepo({
token,
owner: username,
repoName,
});
return res.send(repoStructure);
} catch (error) {
return res.status(500).send([]);
}
};

/**
* completed
*/
export const githubRepoContent = async (req: Request, res: Response) => {
const { repo: repoName } = req.params;
const path = req.params[0];
const { ref } = req.query as { ref: string };

const { username, token } = findById(1);

if (!username || !token) return res.status(404).send([]);

try {
/* path에 따라 객체 또는 객체 배열을 반환, content가 없는 경우 undefind */
const content = await findContent({
token,
owner: username,
repoName,
path,
ref,
});

return res.send(content);
} catch (error) {
return res.status(500).send('fail'); /* todo: error 응답 형태 */
}
};

/**
* completed
*/
export const githubRepoCreate = async (req: Request, res: Response) => {
const { repo: repoName } = req.params;
const { isPrivate } = req.body as { isPrivate: boolean };
const { token } = findById(1);

if (!token) return res.status(404).send([]);

try {
await addRepo({ token, repoName, isPrivate });
return res.send('success');
} catch (error) {
return res.status(500).send('fail');
}
};

/**
* completed
*/
export const githubRepoDelete = async (req: Request, res: Response) => {
const { repo: repoName } = req.params;
const { token } = findById(1);

if (!token) return res.status(404).send([]);

try {
await deleteRepo({ token, repoName });
return res.send('success');
} catch (error) {
return res.status(500).send('fail');
}
};

export const githubFileContentCommit = async (req: Request, res: Response) => {
const { repo: repoName } = req.params;
const path = req.params[0];
const { ref: branchName } = req.query as { ref: string };
const { message, content } = req.body as { message: string; content: string };
const { username, token } = findById(1);

if (!username || !token) return res.status(404).send([]);

try {
const oldContent = await findContent({
token,
owner: username,
repoName,
path,
ref: branchName,
});

if (Array.isArray(oldContent)) return res.status(404).send([]);

/* 기존 content가 없는 경우 -> 새로운 파일 생성 */
if (!oldContent) {
await addContent({
token,
owner: username,
repoName,
path,
content,
branchName,
message,
});
} else {
/* 기존 content가 있는 경우 -> 기존 파일 변경 */
await modifyContent({
token,
owner: username,
repoName,
path,
content,
blobSha: oldContent.sha,
});
}

return res.send('success');
} catch (error) {
return res.status(500).send('fail');
}
};

export const githubCommitList = async (req: Request, res: Response) => {
const { repo: repoName } = req.params;
const octokit = new Octokit();

try {
const response = await octokit.repos.listCommits({
owner: process.env.MY_GITHUB_USERNAME!,
repo: repoName,
});
const commits = response.data.map(commit => ({
sha: commit.sha,
message: commit.commit.message,
author: commit.commit.author?.name,
date: commit.commit.author?.date,
url: commit.html_url,
}));
return res.send(commits);
} catch (error) {
return res.status(500).send('fail');
}
};

export const githubBranchCreate = async (req: Request, res: Response) => {
const { repo: repoName, branch: branchName } = req.params;
const { ref: commitSha } = req.query as { ref: string };
const { username, token } = findById(1);

if (!username || !token) return res.status(404).send([]);

try {
await addBranch({
token,
owner: username,
repoName,
branchName,
commitSha,
});
return res.send('success');
} catch (error) {
return res.status(500).send('fail');
}
};

export const githubBranchDelete = async (req: Request, res: Response) => {
const { repo: repoName, branch: branchName } = req.params;
const { username, token } = findById(1);

if (!username || !token) return res.status(404).send([]);

try {
await deleteBranch({
token,
owner: username,
repoName,
branchName,
});
return res.send('success');
} catch (error) {
return res.status(500).send('fail');
}
};
Loading

0 comments on commit 938020e

Please sign in to comment.