Assign ID's to reviews for use server-side
This commit is contained in:
parent
04197c01b0
commit
e097ed69a7
36
src/main.ts
36
src/main.ts
|
@ -1,8 +1,8 @@
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import http from "http";
|
import http from "http";
|
||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
import { Review, reviewSchema } from "./types";
|
import { serverReviewSchema, ServerSideReview, userReviewSchema } from "./types";
|
||||||
import { bold, checkFile, emp, Logger, Responder } from "./utils";
|
import { appendId, bold, checkFile, emp, Logger, Responder } from "./utils";
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
const logger = new Logger("Simple Review Server");
|
const logger = new Logger("Simple Review Server");
|
||||||
|
@ -19,7 +19,7 @@ http
|
||||||
|
|
||||||
req.on("data", async (chunk) => {
|
req.on("data", async (chunk) => {
|
||||||
if (req.url === "/post") {
|
if (req.url === "/post") {
|
||||||
let data: Review[] = checkFile("data.json", "utf8");
|
let data: ServerSideReview[] = checkFile("data.json", "utf8");
|
||||||
let temp: any;
|
let temp: any;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -33,21 +33,33 @@ http
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await reviewSchema
|
await userReviewSchema
|
||||||
.validate(temp)
|
.validate(temp)
|
||||||
.then((valid) => {
|
.then((valid) => {
|
||||||
req.on("end", () => {
|
req.on("end", () => {
|
||||||
logger.log(`${sender} ~>`, valid);
|
logger.log(`${sender} ~>`, valid);
|
||||||
|
|
||||||
data.push(valid);
|
serverReviewSchema
|
||||||
fs.writeFileSync(
|
.validate(appendId(valid))
|
||||||
"./persist/data.json",
|
.then((valid) => {
|
||||||
JSON.stringify(data, null, 2),
|
data.push(valid);
|
||||||
);
|
fs.writeFileSync(
|
||||||
|
"./persist/data.json",
|
||||||
|
JSON.stringify(data, null, 2),
|
||||||
|
);
|
||||||
|
|
||||||
|
res.writeHead(201, contentType);
|
||||||
|
res.write(response.success("review was sent"));
|
||||||
|
res.end();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
logger.error("Failed to assign ID to review:", err);
|
||||||
|
|
||||||
|
res.writeHead(500, contentType);
|
||||||
|
res.write(response.serverError("could not assign ID to review"));
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
|
||||||
res.writeHead(201, contentType);
|
|
||||||
res.write(response.success("review was sent"));
|
|
||||||
res.end();
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
|
12
src/types.ts
12
src/types.ts
|
@ -1,7 +1,7 @@
|
||||||
import { object, string, number, InferType } from "yup";
|
import { object, string, number, InferType } from "yup";
|
||||||
|
|
||||||
export const reviewSchema = object({
|
export const userReviewSchema = object({
|
||||||
username: string().max(30).required(),
|
username: string().min(2).max(30).required(),
|
||||||
rating: number()
|
rating: number()
|
||||||
.positive()
|
.positive()
|
||||||
.max(5)
|
.max(5)
|
||||||
|
@ -15,4 +15,10 @@ export const reviewSchema = object({
|
||||||
content: string().max(2000).notRequired(),
|
content: string().max(2000).notRequired(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type Review = InferType<typeof reviewSchema>;
|
export const serverReviewSchema = userReviewSchema.shape({
|
||||||
|
id: string().length(6).required()
|
||||||
|
})
|
||||||
|
|
||||||
|
export type UserSideReview = InferType<typeof userReviewSchema>;
|
||||||
|
|
||||||
|
export type ServerSideReview = InferType<typeof serverReviewSchema>;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { Review } from "../types";
|
import { serverReviewSchema, ServerSideReview, UserSideReview } from "../types";
|
||||||
|
|
||||||
export function checkFile(file: string, encoding: fs.EncodingOption): Review[] {
|
export function checkFile(file: string, encoding: fs.EncodingOption): ServerSideReview[] {
|
||||||
const dir = "./persist/";
|
const dir = "./persist/";
|
||||||
const fullPath = dir + file;
|
const fullPath = dir + file;
|
||||||
let final: Review[];
|
let final: ServerSideReview[];
|
||||||
|
|
||||||
if (fs.existsSync(dir)) {
|
if (fs.existsSync(dir)) {
|
||||||
const data = fs.readFileSync(fullPath, encoding);
|
const data = fs.readFileSync(fullPath, encoding);
|
||||||
|
@ -18,3 +18,18 @@ export function checkFile(file: string, encoding: fs.EncodingOption): Review[] {
|
||||||
|
|
||||||
return final;
|
return final;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generates a unique 6-character ID
|
||||||
|
export function generateId(): string {
|
||||||
|
return Math.random().toString(36).replace("0.", "").substring(0, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function appendId(userReview: UserSideReview): ServerSideReview {
|
||||||
|
return {
|
||||||
|
rating: userReview.rating,
|
||||||
|
username: userReview.username,
|
||||||
|
title: userReview.title,
|
||||||
|
content: userReview.content,
|
||||||
|
id: generateId()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,15 @@ export class Responder {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public serverError(errorMessage: string): string {
|
||||||
|
return JSON.stringify({
|
||||||
|
error: {
|
||||||
|
type: "InternalError",
|
||||||
|
message: errorMessage
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public requestError(errorMessage: string): string {
|
public requestError(errorMessage: string): string {
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
error: {
|
error: {
|
||||||
|
|
Loading…
Reference in a new issue