Compare commits

..

3 commits

Author SHA1 Message Date
powermaker450 550d862e09 Prettier 2024-09-20 12:38:39 -04:00
powermaker450 65382936cf Add skip parameter to /api/reviews 2024-09-20 12:38:23 -04:00
powermaker450 1a967876b8 Add max parameter to /api/reviews 2024-09-20 12:30:21 -04:00
5 changed files with 86 additions and 34 deletions

View file

@ -1,6 +1,6 @@
import { Express, Request, Response } from "express"; import { Express, Response } from "express";
import { Logger, Responder, data } from "../utils"; import { Logger, Responder, data } from "../utils";
import { IdRequest, typeJson } from "../types"; import { IdRequest, ReviewRequest, typeJson } from "../types";
import ApiRoute from "../utils/ApiRoute"; import ApiRoute from "../utils/ApiRoute";
export class MessagesResponder extends ApiRoute { export class MessagesResponder extends ApiRoute {
@ -10,9 +10,34 @@ export class MessagesResponder extends ApiRoute {
} }
public async start(): Promise<void> { public async start(): Promise<void> {
this.server.get(this.routeName, (req: Request, res: Response) => { this.server.get(this.routeName, (req: ReviewRequest, res: Response) => {
// This is a mouthful. :sigh:
// If the request parameter "max" is present and it isn't a number
if ((req.query.max && !+req.query.max) || +req.query.max < 1) {
res.writeHead(400, typeJson);
res.write(
Responder.requestError(
"max parameter must be a positive non-zero number or undefined",
),
);
res.end();
return;
}
// Same check as the above one, but for skip
if ((req.query.skip && !+req.query.skip) || +req.query.skip < 1) {
res.writeHead(400, typeJson);
res.write(
Responder.requestError(
"skip parameter must be a number or undefined",
),
);
res.end();
return;
}
const receiver = req.headers["user-agent"]; const receiver = req.headers["user-agent"];
const result = data.getReviews(); const result = data.getReviews(+req.query.max, +req.query.skip);
res.writeHead(200, typeJson); res.writeHead(200, typeJson);
res.write(JSON.stringify(result)); res.write(JSON.stringify(result));
@ -21,35 +46,40 @@ export class MessagesResponder extends ApiRoute {
this.logger.log(`${Logger.emp(receiver)} <~ "${req.path}"`); this.logger.log(`${Logger.emp(receiver)} <~ "${req.path}"`);
}); });
this.server.get(`${this.routeName}/:id`, (req: IdRequest, res: Response) => { this.server.get(
// "req.params.id" is the review ID that was receieved `${this.routeName}/:id`,
// "result" is the review that is identified by that ID, if any (req: IdRequest, res: Response) => {
// "req.params.id" is the review ID that was receieved
// "result" is the review that is identified by that ID, if any
const receiver = req.headers["user-agent"]; const receiver = req.headers["user-agent"];
const result = data.getReviewById(req.params.id); const result = data.getReviewById(req.params.id);
let err = false; let err = false;
if (req.params.id.length === 6) { if (req.params.id.length === 6) {
if (Object.keys(result).length) { if (Object.keys(result).length) {
res.writeHead(200, typeJson); res.writeHead(200, typeJson);
res.write(JSON.stringify(result)); res.write(JSON.stringify(result));
res.end(); res.end();
} else {
res.writeHead(404, typeJson);
res.write(Responder.notFoundError("review not found"));
res.end();
err = true;
}
} else { } else {
res.writeHead(404, typeJson); res.writeHead(400, typeJson);
res.write(Responder.notFoundError("review not found")); res.write(Responder.requestError("review id must be 6 characters"));
res.end(); res.end();
err = true; err = true;
} }
} else {
res.writeHead(400, typeJson);
res.write(Responder.requestError("review id must be 6 characters"));
res.end();
err = true;
}
// If an error was returned to the client, mark their user agent red in the logs // If an error was returned to the client, mark their user agent red in the logs
this.logger.log(`${err ? Logger.err(receiver) : Logger.emp(receiver)} <~ "${req.path}"`); this.logger.log(
}); `${err ? Logger.err(receiver) : Logger.emp(receiver)} <~ "${req.path}"`,
);
},
);
this.complete(); this.complete();
} }

View file

@ -11,7 +11,10 @@ const rating = number()
) )
.required(); .required();
export const typeJson = { "Access-Control-Allow-Origin": "*", "Content-Type": "application/json" }; export const typeJson = {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
};
export const userReviewSchema = object({ export const userReviewSchema = object({
username: string().min(2).max(30).required(), username: string().min(2).max(30).required(),
@ -34,3 +37,10 @@ export interface IdRequest extends Request {
id: string; id: string;
}; };
} }
export interface ReviewRequest extends Request {
query: {
max: string;
skip: string;
};
}

View file

@ -33,6 +33,6 @@ export default class ApiRoute {
res.writeHead(400, typeJson); res.writeHead(400, typeJson);
res.write(Responder.success("ok")); res.write(Responder.success("ok"));
res.end(); res.end();
}) });
} }
} }

View file

@ -6,6 +6,7 @@ import {
UserSideReview, UserSideReview,
} from "../types"; } from "../types";
import { toServerReview, checkFile, stripId } from "./functions"; import { toServerReview, checkFile, stripId } from "./functions";
import { Logger } from "./logger";
export class ReviewData { export class ReviewData {
public data: ServerSideReview[]; public data: ServerSideReview[];
@ -31,11 +32,22 @@ export class ReviewData {
}); });
} }
public getReviews(): ServerSideReview[] { public getReviews(max?: number, skip?: number): ServerSideReview[] {
let final: ServerSideReview[] = []; let final: ServerSideReview[] = [];
// If "max" isn't provided, is Infinity, or is greater than the amount of reviews
const sendAllReviews = !max || max === Infinity || max > this.data.length;
const useList = skip ? this.data.slice(skip, this.data.length) : this.data;
for (const review of this.data) { if (sendAllReviews) {
final.push(review); for (const review of useList) {
final.push(review);
}
} else {
for (const review of useList) {
while (final.length !== max) {
final.push(review);
}
}
} }
return final; return final;

View file

@ -47,8 +47,8 @@ export class Responder {
return JSON.stringify({ return JSON.stringify({
error: { error: {
type: "notFoundError", type: "notFoundError",
message: errorMessage message: errorMessage,
} },
}); });
} }
} }