Skip to content

Commit

Permalink
feat: Add downloadCommitDotShHandler and error classes for handlers.
Browse files Browse the repository at this point in the history
  • Loading branch information
wajeht committed Jul 12, 2024
1 parent ced7ebe commit 9aeb6bc
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 7 deletions.
6 changes: 4 additions & 2 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import express from 'express';
import { notFoundMiddleware, errorMiddleware, limitIPsMiddleware } from './middleware';
import { generateCommitMessageHandler, healthzHandler, indexHandler } from './handler';
import { downloadCommitDotShHandler, generateCommitMessageHandler, healthzHandler, indexHandler } from './handler';

const app = express();

Expand All @@ -10,7 +10,9 @@ app.use(express.urlencoded({ extended: true }));

app.get('/healthz', healthzHandler)

app.get('/', limitIPsMiddleware, indexHandler)
app.get('/commit.sh', downloadCommitDotShHandler)

app.get('/', indexHandler)

app.post('/', limitIPsMiddleware, generateCommitMessageHandler)

Expand Down
38 changes: 38 additions & 0 deletions src/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
export class HttpError extends Error {
statusCode: number;

constructor(statusCode = 500, message = 'Oh no, something went wrong!') {
super(message);
this.statusCode = statusCode;
}
}

export class ForbiddenError extends HttpError {
constructor(message = 'Forbidden') {
super(403, message);
}
}

export class UnauthorizedError extends HttpError {
constructor(message = 'Unauthorized') {
super(401, message);
}
}

export class NotFoundError extends HttpError {
constructor(message = 'Not Found') {
super(404, message);
}
}

export class ValidationError extends HttpError {
constructor(message = 'Validation Error') {
super(422, message);
}
}

export class UnimplementedFunctionError extends HttpError {
constructor(message = 'Function Not Implemented') {
super(501, message);
}
}
21 changes: 18 additions & 3 deletions src/handler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import OpenAI from 'openai';
import path from "node:path";
import { appConfig } from "./config";
import { NextFunction, Request, Response} from "express";
import { ValidationError } from './error';

export function healthzHandler(req: Request, res: Response, next: NextFunction) {
try {
Expand All @@ -10,9 +12,22 @@ export function healthzHandler(req: Request, res: Response, next: NextFunction)
}
}

export function indexHandler(req: Request, res: Response, next: NextFunction){
export function downloadCommitDotShHandler(req: Request, res: Response, next: NextFunction){
try {
const message = `run this command: 'git --no-pager diff | jq -Rs '{"diff": .}' | curl -X POST "http://localhost" -H "Content-Type: application/json" -d @-'`
const commitDotSh = path.resolve(path.join(process.cwd(), 'commit.sh'));
return res.status(200).download(commitDotSh);
} catch (error) {
next(error);
}
}

export function indexHandler(req: Request, res: Response, next: NextFunction) {
try {
const host = req.hostname;
const protocol = req.protocol;
const port = req.get('host')?.split(':')[1] || '';
const url = `${protocol}://${host}${port ? ':' + port : ''}`;
const message = `run this command: "wget ${url}/commit.sh"`;
return res.status(200).json({ message });
} catch (error) {
next(error);
Expand All @@ -24,7 +39,7 @@ export async function generateCommitMessageHandler (req: Request, res: Response,
const { diff } = req.body;

if (diff.trim() === '') {
throw new Error('must not be empty!')
throw new ValidationError('must not be empty!')
}

const openai = new OpenAI({ apiKey: appConfig.OPENAI_API_KEY });
Expand Down
25 changes: 23 additions & 2 deletions src/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { NextFunction, Request, Response} from "express";
import { appConfig } from "./config";
import { HttpError, ForbiddenError, UnauthorizedError, NotFoundError, ValidationError, UnimplementedFunctionError } from './error';


export function limitIPsMiddleware(req: Request, res: Response, next: NextFunction){
try {
Expand All @@ -8,7 +10,7 @@ export function limitIPsMiddleware(req: Request, res: Response, next: NextFuncti
const ip = (req.headers['x-forwarded-for'] || req.socket.remoteAddress).split(', ')[0];

if (!ips!.includes(ip)) {
throw new Error('no');
throw new ForbiddenError();
}

next();
Expand All @@ -21,6 +23,25 @@ export function notFoundMiddleware(req: Request, res: Response, next: NextFuncti
return res.status(404).json({ message: "not found" });
}


export function errorMiddleware(error: Error, req: Request, res: Response, next: NextFunction) {
return res.status(500).json({ message: "error" });
const errorMap = new Map([
[ForbiddenError, 403],
[UnauthorizedError, 401],
[NotFoundError, 404],
[ValidationError, 422],
[UnimplementedFunctionError, 501]
]);

for (const [ErrorClass, statusCode] of errorMap) {
if (error instanceof ErrorClass) {
return res.status(statusCode).json({ message: error.message });
}
}

if (error instanceof HttpError) {
return res.status(error.statusCode).json({ message: error.message });
}

return res.status(500).json({ message: "Oh no, something went wrong!" });
}

0 comments on commit 9aeb6bc

Please sign in to comment.