refactor: prisma and file based router

This commit is contained in:
2023-10-20 22:28:00 +02:00
parent 4164f54695
commit a19ce4aeba
16 changed files with 155 additions and 214 deletions

View File

@@ -2,7 +2,7 @@
"trailingComma": "es5",
"useTabs": true,
"semi": false,
"singleQuote": false,
"singleQuote": true,
"quoteProps": "preserve",
"tabWidth": 4
}

View File

@@ -15,10 +15,7 @@ FROM node:lts-alpine AS final
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/schemas ./schemas
COPY --from=build /app/util ./util
COPY --from=build /app/routes ./routes
COPY --from=build /app/docs ./docs
COPY --from=build /app/prisma ./prisma
COPY --from=build /app/public ./public
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/package.json ./package.json

View File

@@ -1,44 +0,0 @@
{
"swagger": "2.0",
"info": {
"title": "Sr Izan API",
"description": "Image recognition stuff for now lol",
"version": "1.0.0"
},
"host": "api.srizan.dev",
"basePath": "/",
"schemes": [
"https"
],
"paths": {
"/misc/download": {
"get": {
"summary": "Download images from a URL",
"parameters": [
{
"in": "query",
"name": "url",
"type": "string",
"required": true,
"description": "The URL (https and stuff)"
},
{
"in": "query",
"name": "type",
"type": "string",
"required": true,
"description": "The file type (png, jpg, jpeg or gif)"
}
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad Request"
}
}
}
}
}
}

View File

@@ -1,17 +1,16 @@
import mongoose from "mongoose"
import express from "express"
import 'dotenv/config'
import bodyParser from "body-parser"
import rateLimit from "express-rate-limit"
import { consolelogTime } from "./util/consolelogTime.js"
import swagger from './docs/swagger.json' assert { type: 'json' }
import swaggerUI from 'swagger-ui-express'
import cors from 'cors'
import { router } from "express-file-routing"
import path from 'node:path'
import { fileURLToPath } from 'node:url';
import { PrismaClient } from "@prisma/client"
/* Mongoose */
await mongoose.connect(`${process.env.MONGODB}`).then(() => {
consolelogTime(`Connected to MongoDB!`)
})
const dirname = path.dirname(fileURLToPath(import.meta.url));
/* MongoDB */
export const prisma = new PrismaClient()
/* Express configuration */
const app = express()
@@ -21,49 +20,15 @@ const limiter = rateLimit({
message: { success: false, reason: "you just got ratelimited", error: "You just got ratelimited." },
standardHeaders: true,
})
app.use(bodyParser.json())
app.use('/docs', swaggerUI.serve, swaggerUI.setup(swagger));
app.use(express.json())
app.use(express.static('public'))
app.use(limiter)
app.disable("x-powered-by")
/* All route imports */
import newTime from "./routes/sern/newTime.js"
import getTime from "./routes/sern/getTime.js"
import deleteTime from "./routes/sern/deleteTime.js"
import download from "./routes/misc/download.js"
import saveTranscript from "./routes/transcriptor/saveTranscript.js"
import getTranscript from "./routes/transcriptor/getTranscript.js"
router({ directory: path.join(dirname, '/routes') }).then((r) => {
app.use("/", r);
app.use("/sern/newTime", limiter)
app.post("/sern/newTime", async (req, res) => {
newTime(req, res)
})
app.use("/sern/getTime", limiter)
app.get("/sern/getTime", async (req, res) => {
getTime(req, res)
})
app.use("/sern/newTime", limiter)
app.delete("/sern/deleteTime", async (req, res) => {
deleteTime(req, res)
})
app.use("/misc/download", limiter)
app.get("/misc/download", async (req, res) => {
download(req, res)
})
app.use("/transcriptor/save", limiter)
app.post("/transcriptor/save", (req, res) => {
saveTranscript(req, res)
})
app.use("/transcriptor/get", limiter)
app.get("/transcriptor/get", cors(), (req, res) => {
getTranscript(req, res)
})
app.listen(7272, () => {
consolelogTime(`Listening`)
})
app.listen(7272, () => {
consolelogTime(`Listening`)
})
});

View File

@@ -20,18 +20,19 @@
},
"homepage": "https://github.com/SrIzan10/api#readme",
"dependencies": {
"@prisma/client": "^5.4.2",
"axios": "^1.2.5",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.1",
"express-file-routing": "^3.0.3",
"express-rate-limit": "^6.6.0",
"mongoose": "^6.6.5",
"swagger-ui-express": "^4.6.0"
"mongoose": "^6.6.5"
},
"devDependencies": {
"@types/cors": "^2.8.13",
"@types/express": "^4.17.14",
"@types/swagger-ui-express": "^4.1.3",
"prisma": "^5.4.2",
"typescript": "^4.8.4"
}
}

24
prisma/schema.prisma Normal file
View File

@@ -0,0 +1,24 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mongodb"
url = env("MONGODB")
}
model sern_timezones {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @default(0) @map("__v") @ignore
timezone String
userid String @unique
}
model transcripts {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @default(0) @map("__v") @ignore
guild String
msgid String @unique
text String
username String
}

View File

@@ -7,7 +7,6 @@
<title>Sr Izan's API</title>
</head>
<body>
<h1>hi this is my shitty api tbh</h1>
<a href="docs/">really bad docs</a>
<p>wow an api</p>
</body>
</html>

View File

@@ -1,6 +1,5 @@
import axios from "axios"
import { Request, Response } from "express"
import type { Handler } from "express"
export default async function download(req: Request, res: Response) {
export const get: Handler = async (req, res) => {
res.send('Disabled due to security reasons')
}

View File

@@ -1,23 +1,28 @@
import sernTime from "../../schemas/sern-time.js"
import { Request, Response } from "express"
import { prisma } from '../../index.js'
import type { Handler } from 'express'
export default async function deleteTime(req: Request, res: Response) {
if (req.query.userid && req.query.key === process.env.SERN_TIME) {
sernTime.exists({ userid: req.query.userid }, async function (err, doc) {
if (err) throw err
if (doc) {
const timezone = await sernTime.findOne({ userid: req.query.userid })
await timezone!.delete()
res.json({"ok": "done"})
} else {
res.status(400).json({
"error": "the user doesn't exist",
})
}
export const del: Handler = async (req, res) => {
if (req.query.userid && req.query.key === process.env.SERN_TIME) {
if (
await prisma.sern_timezones.findUnique({
where: { userid: req.query.userid as string },
})
)
return res.status(400).json({
error: "the user doesn't exist",
})
await prisma.sern_timezones.delete({
where: {
userid: req.query.userid as string,
},
}).catch(() => {
return res.status(500).json({ error: 'that didnt work' })
})
res.json({ ok: 'done' })
} else {
res.status(400).json({
"error": "make sure you have the userid param and the right key",
error: 'make sure you have the userid param and the right key',
})
}
}

View File

@@ -1,22 +1,21 @@
import sernTime from "../../schemas/sern-time.js"
import { Request, Response } from "express"
import { prisma } from "../../index.js"
import type { Handler } from "express"
export default async function getTime(req: Request, res: Response) {
export const get: Handler = async (req, res) => {
if (req.query.userid) {
sernTime.exists({ userid: req.query.userid }, async function (err, doc) {
if (err) throw err
if (doc) {
const timezone = (await sernTime.findOne({ userid: req.query.userid }))?.timezone
res.json({"timezone": timezone})
} else {
res.status(400).json({
"error": "you don't exist in the database",
})
if (await prisma.sern_timezones.count({ where: { userid: req.query.userid as string } }) === 0)
return res.status(400).json({
error: "the user doesn't exist",
})
const timezone = await prisma.sern_timezones.findUnique({
where: {
userid: req.query.userid as string,
}
})
res.json({ timezone: timezone?.timezone })
} else {
res.status(400).json({
"error": "make sure you have the userid param",
error: "make sure you have the userid param",
})
}
}

View File

@@ -1,34 +1,29 @@
import sernTime from "../../schemas/sern-time.js"
import { Request, Response } from "express"
import { prisma } from "../../index.js"
import type { Handler } from "express"
export default async function newTime(req: Request, res: Response) {
export const post: Handler = async (req, res) => {
if (
req.body.timezone &&
req.body.key === process.env.SERN_TIME &&
req.body.userid
) {
sernTime.exists({ userid: req.body.userid }, function (err, doc) {
if (err) throw err
if (doc) {
res.status(400).json({ "error": "You already created a timezone!" })
} else {
if (doc) {
res
.status(400)
.json({ "error": "User already exists in the database." })
} else {
const saveToDB = new sernTime({
timezone: req.body.timezone,
userid: req.body.userid,
})
saveToDB.save()
res.json({ "ok": "you were added successfully!" })
}
if (await prisma.sern_timezones.count({ where: { userid: req.body.userid as string } }) !== 0)
return res.status(400).json({ "error": "User already exists in the database." })
const userid = req.body.userid as string
const timezone = req.body.timezone as string
await prisma.sern_timezones.create({
data: {
userid,
timezone
}
}).catch(() => {
return res.status(500).json({ "error": "internal server error" })
})
res.json({ "ok": "you were added successfully!" })
} else {
res.status(400).json({
"error": "make sure you have the right params.",
"error": "make sure you have the right params",
})
}
}

View File

@@ -1,11 +1,16 @@
import { Request, Response } from "express"
import db from "../../schemas/transcripts.js"
import type { Handler } from "express"
import { prisma } from "../../index.js"
export default async function getTranscript(req: Request, res: Response) {
try {
var database = await db.findOne({ msgid: req.query.msgid })
} catch {
return res.status(400).send({ success: false, reason: "msgid not found in db" })
}
export const get: Handler = async (req, res) => {
if (!req.query.msgid) return res.status(400).json({ error: "msgid is required" })
if (await prisma.transcripts.count({ where: { msgid: req.query.msgid as string } }) === 0)
return res.status(400).json({
error: "the message doesn't exist",
})
const database = await prisma.transcripts.findUnique({
where: {
msgid: req.query.msgid as string
}
})
res.status(200).send({ text: database?.text, username: database?.username, guild: database?.guild, msgid: database?.msgid })
}

View File

@@ -1,15 +1,18 @@
import { Request, Response } from "express"
import db from "../../schemas/transcripts.js"
import type { Handler } from "express"
import { prisma } from "../../index.js"
export default async function saveTranscript(req: Request, res: Response) {
export const post: Handler = async (req, res) => {
if (!req.body.token || req.body.token !== process.env.TRANSCRIPTS) return res.status(400).send({ success: false, reason: "no key?" })
const data = req.body
const database = new db({
guild: data.guild,
msgid: data.msgid,
text: data.text,
username: data.username
await prisma.transcripts.create({
data: {
msgid: data.msgid,
username: data.username,
guild: data.guild,
text: data.text
}
}).catch(() => {
return res.status(500).json({ success: false, error: 'that didnt work' })
})
await database.save()
res.send({ success: true })
}

View File

@@ -1,7 +0,0 @@
import { model, Schema, Model } from "mongoose";
const schema = new Schema({
timezone: { type: String, required: true },
userid: { type: String, required: true }
});
const db = model('sern-timezones', schema)
export default db;

View File

@@ -1,9 +0,0 @@
import { model, Schema, Model } from "mongoose";
const schema = new Schema({
text: { type: String, required: true },
username: { type: String, required: true },
guild: { type: String, required: true },
msgid: { type: String, required: true }
});
const db = model('transcripts', schema)
export default db;

View File

@@ -480,6 +480,23 @@
dependencies:
sparse-bitfield "^3.0.3"
"@prisma/client@^5.4.2":
version "5.4.2"
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.4.2.tgz#786f9c1d8f06d955933004ac638d14da4bf14025"
integrity sha512-2xsPaz4EaMKj1WS9iW6MlPhmbqtBsXAOeVttSePp8vTFTtvzh2hZbDgswwBdSCgPzmmwF+tLB259QzggvCmJqA==
dependencies:
"@prisma/engines-version" "5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574"
"@prisma/engines-version@5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574":
version "5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574"
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574.tgz#ff14f2926890edee47e8f1d08df7b4f392ee34bf"
integrity sha512-wvupDL4AA1vf4TQNANg7kR7y98ITqPsk6aacfBxZKtrJKRIsWjURHkZCGcQliHdqCiW/hGreO6d6ZuSv9MhdAA==
"@prisma/engines@5.4.2":
version "5.4.2"
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.4.2.tgz#ba2b7faeb227c76e423e88f962afe6a031319f3f"
integrity sha512-fqeucJ3LH0e1eyFdT0zRx+oETLancu5+n4lhiYECyEz6H2RDskPJHJYHkVc0LhkU4Uv7fuEnppKU3nVKNzMh8g==
"@smithy/abort-controller@^2.0.11":
version "2.0.11"
resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-2.0.11.tgz#e1d96a2ecbf103d0b075a7456ce3afeeb9f76a87"
@@ -861,7 +878,7 @@
"@types/range-parser" "*"
"@types/send" "*"
"@types/express@*", "@types/express@^4.17.14":
"@types/express@^4.17.14":
version "4.17.18"
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.18.tgz#efabf5c4495c1880df1bdffee604b143b29c4a95"
integrity sha512-Sxv8BSLLgsBYmcnGdGjjEjqET2U+AKAdCRODmMiq02FgjwuV75Ut85DRpvFjyw/Mk0vgUOliGRU0UUmuuZHByQ==
@@ -918,14 +935,6 @@
"@types/mime" "*"
"@types/node" "*"
"@types/swagger-ui-express@^4.1.3":
version "4.1.4"
resolved "https://registry.yarnpkg.com/@types/swagger-ui-express/-/swagger-ui-express-4.1.4.tgz#4cf91ed46a4d17797a38cbf9805ad6fa4730dad6"
integrity sha512-h6dfIPFveCJKpStDtjrB+4pig4DAf9Uu2Z51RB7Fj3s6AifexmqhZxBoG50K/k3Afz7wyXsIAY5ZIDTlC2VjrQ==
dependencies:
"@types/express" "*"
"@types/serve-static" "*"
"@types/webidl-conversions@*":
version "7.0.1"
resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.1.tgz#2b9a2062b39a7272343c185cdb884f2e52188f75"
@@ -1113,6 +1122,11 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
express-file-routing@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/express-file-routing/-/express-file-routing-3.0.3.tgz#4643ef7a015c801b934191122aeded92d24bd869"
integrity sha512-0936IhPc64moJHAG1Fz3SLCi0Upt6ahsbocrC6hdPUgmHY2018wjVrbln0HP67JoWFUdmmzypYiIHjF898s0hA==
express-rate-limit@^6.6.0:
version "6.11.2"
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-6.11.2.tgz#6c42035603d3b52e4e2fb59f6ebaa89e628ef980"
@@ -1401,6 +1415,13 @@ path-to-regexp@0.1.7:
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
prisma@^5.4.2:
version "5.4.2"
resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.4.2.tgz#7eac9276439ec7073ec697c6c0dfa259d96e955e"
integrity sha512-GDMZwZy7mysB2oXU+angQqJ90iaPFdD0rHaZNkn+dio5NRkGLmMqmXs31//tg/qXT3iB0cTQwnGGQNuirhSTZg==
dependencies:
"@prisma/engines" "5.4.2"
proxy-addr@~2.0.7:
version "2.0.7"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
@@ -1529,18 +1550,6 @@ strnum@^1.0.5:
resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db"
integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==
swagger-ui-dist@>=4.11.0:
version "5.9.0"
resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-5.9.0.tgz#d52b6cf52fd0a8e6930866c402aaa793fe4e3f76"
integrity sha512-NUHSYoe5XRTk/Are8jPJ6phzBh3l9l33nEyXosM17QInoV95/jng8+PuSGtbD407QoPf93MH3Bkh773OgesJpA==
swagger-ui-express@^4.6.0:
version "4.6.3"
resolved "https://registry.yarnpkg.com/swagger-ui-express/-/swagger-ui-express-4.6.3.tgz#870d0892654fe80e6970a2d680e22521acd2dc19"
integrity sha512-CDje4PndhTD2HkgyKH3pab+LKspDeB/NhPN2OF1j+piYIamQqBYwAXWESOT1Yju2xFg51bRW9sUng2WxDjzArw==
dependencies:
swagger-ui-dist ">=4.11.0"
toidentifier@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"