mirror of
https://github.com/Steffo99/festa.git
synced 2024-12-22 22:54:22 +00:00
this turned out to be pretty clean tbh
This commit is contained in:
parent
9f351b1e36
commit
38e2e7b522
3 changed files with 29 additions and 10 deletions
|
@ -3,7 +3,7 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "dotenv -e .env.local prisma db push && dotenv -e .env.local prisma generate && dotenv -e .env.local next dev",
|
"dev": "dotenv -e .env.local prisma db push && dotenv -e .env.local prisma generate && NODE_OPTIONS=--inspect dotenv -e .env.local next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint",
|
"lint": "next lint",
|
||||||
|
|
|
@ -1,17 +1,23 @@
|
||||||
import { client } from "../../../utils/prismaClient";
|
import { client } from "../../../utils/prismaClient";
|
||||||
import { NextApiRequest, NextApiResponse } from "next";
|
import { NextApiRequest, NextApiResponse } from "next";
|
||||||
import { ApiResult } from "../../../types/api";
|
import { ApiResult } from "../../../types/api";
|
||||||
import { restInPeace } from "../../../utils/restInPeace";
|
import { Model, restInPeace } from "../../../utils/restInPeace";
|
||||||
import { default as cryptoRandomString} from "crypto-random-string";
|
import { default as cryptoRandomString} from "crypto-random-string";
|
||||||
import { handleInterrupts } from "../../../utils/interrupt";
|
import { handleInterrupts, Interrupt } from "../../../utils/interrupt";
|
||||||
import { authorizeUser } from "../../../utils/apiAuth";
|
import { authorizeUser } from "../../../utils/apiAuth";
|
||||||
import { User } from "@prisma/client";
|
import { Event } from "@prisma/client";
|
||||||
|
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResult<Event | Event[]>>) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResult<Event | Event[]>>) {
|
||||||
handleInterrupts(res, async () => {
|
handleInterrupts(res, async () => {
|
||||||
const user = await authorizeUser(req, res)
|
const user = await authorizeUser(req, res)
|
||||||
|
|
||||||
|
const canEdit = async (model: Model, obj?: Event) => {
|
||||||
|
if(obj && obj.creatorId !== user.id) {
|
||||||
|
throw new Interrupt(403, {error: "Only the creator can edit an event"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const which = {
|
const which = {
|
||||||
slug: req.query.slug
|
slug: req.query.slug
|
||||||
}
|
}
|
||||||
|
@ -28,7 +34,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
||||||
model: client.event,
|
model: client.event,
|
||||||
retrieve: {which},
|
retrieve: {which},
|
||||||
create: {create},
|
create: {create},
|
||||||
// TODO: this might prove problematic
|
upsert: {create, update, before: canEdit},
|
||||||
|
update: {update, before: canEdit},
|
||||||
|
destroy: {before: canEdit},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ import { ApiError, ApiResult } from "../types/api";
|
||||||
|
|
||||||
|
|
||||||
// I don't know what the typing of a Prisma model is.
|
// I don't know what the typing of a Prisma model is.
|
||||||
type Model = any
|
export type Model = any
|
||||||
|
|
||||||
|
|
||||||
type RestInPeaceOptions<T> = {
|
type RestInPeaceOptions<T> = {
|
||||||
|
@ -97,7 +97,7 @@ export async function restInPeace<T>(req: NextApiRequest, res: NextApiResponse<A
|
||||||
|
|
||||||
|
|
||||||
interface OperationOptions<T> {
|
interface OperationOptions<T> {
|
||||||
before?: (model: T) => Promise<void>,
|
before?: (model: T, obj?: any) => Promise<void>,
|
||||||
after?: (model: T, obj?: any) => Promise<any>,
|
after?: (model: T, obj?: any) => Promise<any>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +106,7 @@ interface OperationOptions<T> {
|
||||||
|
|
||||||
|
|
||||||
interface HeadOptions<T> extends OperationOptions<T> {
|
interface HeadOptions<T> extends OperationOptions<T> {
|
||||||
|
before?: (model: T) => Promise<void>,
|
||||||
after?: (model: T) => Promise<void>,
|
after?: (model: T) => Promise<void>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +124,7 @@ async function handleHead<T>(res: NextApiResponse<"">, model: Model, options: He
|
||||||
|
|
||||||
|
|
||||||
interface OptionsOptions<T> extends OperationOptions<T> {
|
interface OptionsOptions<T> extends OperationOptions<T> {
|
||||||
|
before?: (model: T) => Promise<void>,
|
||||||
after?: (model: T) => Promise<void>,
|
after?: (model: T) => Promise<void>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +147,7 @@ interface ListOptions<T> extends OperationOptions<T> {
|
||||||
*/
|
*/
|
||||||
where?: object,
|
where?: object,
|
||||||
|
|
||||||
|
before?: (model: T) => Promise<void>,
|
||||||
after?: (model: T, obj: T[]) => Promise<T[]>,
|
after?: (model: T, obj: T[]) => Promise<T[]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +173,7 @@ interface RetrieveOptions<T> extends OperationOptions<T> {
|
||||||
*/
|
*/
|
||||||
which?: object,
|
which?: object,
|
||||||
|
|
||||||
|
before?: (model: T) => Promise<void>,
|
||||||
after?: (model: T, obj: T) => Promise<T>,
|
after?: (model: T, obj: T) => Promise<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,6 +200,7 @@ interface CreateOptions<T> extends OperationOptions<T> {
|
||||||
*/
|
*/
|
||||||
create: object,
|
create: object,
|
||||||
|
|
||||||
|
before?: (model: T) => Promise<void>,
|
||||||
after?: (model: T, obj: T) => Promise<T>,
|
after?: (model: T, obj: T) => Promise<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,6 +236,7 @@ interface UpsertOptions<T> extends OperationOptions<T> {
|
||||||
*/
|
*/
|
||||||
update: object,
|
update: object,
|
||||||
|
|
||||||
|
before?: (model: T, obj?: T) => Promise<void>,
|
||||||
after?: (model: T, obj: T) => Promise<T>,
|
after?: (model: T, obj: T) => Promise<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +244,8 @@ interface UpsertOptions<T> extends OperationOptions<T> {
|
||||||
* Handle a `PUT` HTTP request where a single item is either created or updated.
|
* Handle a `PUT` HTTP request where a single item is either created or updated.
|
||||||
*/
|
*/
|
||||||
async function handleUpsert<T>(res: NextApiResponse<ApiResult<T>>, model: Model, options: UpsertOptions<T>) {
|
async function handleUpsert<T>(res: NextApiResponse<ApiResult<T>>, model: Model, options: UpsertOptions<T>) {
|
||||||
await options.before?.(model)
|
const initialObj = await model.findUnique({ where: options.which })
|
||||||
|
await options.before?.(model, initialObj)
|
||||||
const obj = await model.upsert({
|
const obj = await model.upsert({
|
||||||
where: options.which,
|
where: options.which,
|
||||||
create: options.create,
|
create: options.create,
|
||||||
|
@ -265,6 +272,7 @@ interface UpdateOptions<T> extends OperationOptions<T> {
|
||||||
*/
|
*/
|
||||||
update: object,
|
update: object,
|
||||||
|
|
||||||
|
before?: (model: T, obj?: T) => Promise<void>,
|
||||||
after?: (model: T, obj: T) => Promise<T>,
|
after?: (model: T, obj: T) => Promise<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +280,8 @@ interface UpdateOptions<T> extends OperationOptions<T> {
|
||||||
* Handle a `PATCH` HTTP request where a single item is updated.
|
* Handle a `PATCH` HTTP request where a single item is updated.
|
||||||
*/
|
*/
|
||||||
async function handleUpdate<T>(res: NextApiResponse<ApiResult<T>>, model: Model, options: UpdateOptions<T>) {
|
async function handleUpdate<T>(res: NextApiResponse<ApiResult<T>>, model: Model, options: UpdateOptions<T>) {
|
||||||
await options.before?.(model)
|
const initialObj = await model.findUnique({ where: options.which })
|
||||||
|
await options.before?.(model, initialObj)
|
||||||
const obj = await model.update({
|
const obj = await model.update({
|
||||||
where: options.which,
|
where: options.which,
|
||||||
data: options.update,
|
data: options.update,
|
||||||
|
@ -293,6 +302,7 @@ interface DestroyOptions<T> extends OperationOptions<T> {
|
||||||
*/
|
*/
|
||||||
which?: object,
|
which?: object,
|
||||||
|
|
||||||
|
before?: (model: T, obj?: T) => Promise<void>,
|
||||||
after?: (model: T) => Promise<void>,
|
after?: (model: T) => Promise<void>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +310,8 @@ interface DestroyOptions<T> extends OperationOptions<T> {
|
||||||
* Handle a `DELETE` HTTP request where a single item is destroyed.
|
* Handle a `DELETE` HTTP request where a single item is destroyed.
|
||||||
*/
|
*/
|
||||||
async function handleDestroy<T>(res: NextApiResponse<ApiResult<T>>, model: Model, options: DestroyOptions<T>) {
|
async function handleDestroy<T>(res: NextApiResponse<ApiResult<T>>, model: Model, options: DestroyOptions<T>) {
|
||||||
await options.before?.(model)
|
const initialObj = await model.findUnique({ where: options.which })
|
||||||
|
await options.before?.(model, initialObj)
|
||||||
await model.delete({
|
await model.delete({
|
||||||
where: options.which,
|
where: options.which,
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue