Skip to content

Commit 1b76819

Browse files
committed
added next-api-decorators, list & items api routes
1 parent 3166443 commit 1b76819

File tree

10 files changed

+196
-3686
lines changed

10 files changed

+196
-3686
lines changed

Diff for: package-lock.json

+18-3,660
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99
"lint": "next lint"
1010
},
1111
"dependencies": {
12+
"@next-auth/prisma-adapter": "^1.0.5",
1213
"@prisma/client": "4.6.1",
1314
"next": "13.0.3",
15+
"next-api-decorators": "^2.0.0",
16+
"next-auth": "^4.15.0",
1417
"react": "18.2.0",
1518
"react-dom": "18.2.0",
16-
"sass": "^1.56.1",
17-
"@next-auth/prisma-adapter": "^1.0.5",
18-
"next-auth": "^4.15.0"
19+
"sass": "^1.56.1"
1920
},
2021
"devDependencies": {
2122
"@tsconfig/recommended": "^1.0.1",

Diff for: pages/api/items/index.ts

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { getSession } from "next-auth/react";
2+
import type { NextApiRequest, NextApiResponse } from "next/types";
3+
import prisma from "lib/prisma";
4+
import {
5+
Body,
6+
createHandler,
7+
Get,
8+
HttpCode,
9+
Post,
10+
Req
11+
} from "next-api-decorators";
12+
import type { ItemBody } from "types/prisma.types";
13+
import { getUser } from "utils/helpers";
14+
15+
// GET,POST /api/items
16+
class ItemsHandler {
17+
@Post()
18+
@HttpCode(201)
19+
async create(@Body() body: ItemBody, @Req() req: NextApiRequest) {
20+
const user = await getUser(req);
21+
const { name, note, image, categoryId } = body;
22+
const item = prisma.item.create({
23+
data: {
24+
name: name,
25+
note: note,
26+
image: image,
27+
categoryId: categoryId,
28+
createdBy: user.id
29+
}
30+
});
31+
return item;
32+
}
33+
34+
@Get()
35+
async getItems(@Req() req: NextApiRequest) {
36+
const user = await getUser(req);
37+
const items = await prisma.item.findMany({
38+
select: {
39+
name: true,
40+
category: true,
41+
image: true,
42+
note: true
43+
},
44+
where: {
45+
createdBy: user.id
46+
}
47+
});
48+
return items;
49+
}
50+
}
51+
export default createHandler(ItemsHandler);

Diff for: pages/api/list/index.ts

-10
This file was deleted.

Diff for: pages/api/lists/index.ts

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import type { NextApiRequest, NextApiResponse } from "next/types";
2+
import prisma from "lib/prisma";
3+
import type { ListBody } from "types/prisma.types";
4+
import {
5+
Body,
6+
createHandler,
7+
Get,
8+
HttpCode,
9+
Post,
10+
Req
11+
} from "next-api-decorators";
12+
import { getUser } from "utils/helpers";
13+
14+
// GET,POST /api/lists
15+
class ListsHandler {
16+
@Post()
17+
@HttpCode(201)
18+
async create(@Body() body: ListBody, @Req() req: NextApiRequest) {
19+
const user = await getUser(req);
20+
const { name } = body;
21+
const item = prisma.list.create({
22+
data: {
23+
name: name,
24+
createdBy: user.id
25+
}
26+
});
27+
return item;
28+
}
29+
30+
@Get()
31+
async getItems(@Req() req: NextApiRequest) {
32+
const user = await getUser(req);
33+
const items = await prisma.list.findMany({
34+
select: {
35+
name: true,
36+
createdAt: true,
37+
listItems: {
38+
select: {
39+
item: {
40+
select: {
41+
name: true,
42+
category: {
43+
select: {
44+
label: true
45+
}
46+
}
47+
}
48+
},
49+
qty: true
50+
}
51+
}
52+
},
53+
where: {
54+
createdBy: user.id
55+
}
56+
});
57+
return items;
58+
}
59+
}
60+
export default createHandler(ListsHandler);

Diff for: prisma/schema.prisma

+14-12
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,17 @@ model Session {
3737
}
3838

3939
model User {
40-
id String @id @default(auto()) @map("_id") @db.ObjectId
40+
id String @id @default(auto()) @map("_id") @db.ObjectId
4141
name String?
42-
email String? @unique
42+
email String? @unique
4343
emailVerified DateTime?
4444
image String?
45-
createdAt DateTime? @default(now()) @map(name: "created_at")
46-
updatedAt DateTime? @updatedAt @map(name: "updated_at")
45+
createdAt DateTime? @default(now()) @map(name: "created_at")
46+
updatedAt DateTime? @updatedAt @map(name: "updated_at")
4747
accounts Account[]
4848
sessions Session[]
49-
categories Category[]
5049
lists List[]
50+
items Item[]
5151
}
5252

5353
model VerificationToken {
@@ -60,16 +60,14 @@ model VerificationToken {
6060
}
6161

6262
model Category {
63-
id String @id @default(auto()) @map("_id") @db.ObjectId
64-
createdBy String @map("user_id") @db.ObjectId
65-
label String @unique
66-
items Item[]
67-
user User? @relation(fields: [createdBy], references: [id])
63+
id String @id @default(auto()) @map("_id") @db.ObjectId
64+
label String @unique
65+
items Item[]
6866
}
6967

7068
model List {
7169
id String @id @default(auto()) @map("_id") @db.ObjectId
72-
createdBy String @map("user_id") @db.ObjectId
70+
createdBy String
7371
name String
7472
createdAt DateTime? @default(now())
7573
user User? @relation(fields: [createdBy], references: [id])
@@ -78,12 +76,16 @@ model List {
7876

7977
model Item {
8078
id String @id @default(auto()) @map("_id") @db.ObjectId
81-
name String @unique
79+
name String
8280
note String?
8381
image String?
82+
createdBy String
83+
user User? @relation(fields: [createdBy], references: [id])
8484
category Category @relation(fields: [categoryId], references: [id])
8585
categoryId String @db.ObjectId
8686
listItem ListItem[]
87+
88+
@@unique([name, createdBy])
8789
}
8890

8991
model ListItem {

Diff for: tsconfig.json

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
"jsx": "preserve",
1616
"incremental": true,
1717
"baseUrl": "./",
18+
"experimentalDecorators": true,
19+
"emitDecoratorMetadata": true
1820
},
1921
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
2022
"exclude": ["node_modules"]

Diff for: types/prisma.types.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
11
import { Prisma } from "@prisma/client";
22

3+
const itemBody = Prisma.validator<Prisma.ItemArgs>()({
4+
select: {
5+
name: true,
6+
note: true,
7+
image: true,
8+
categoryId: true
9+
}
10+
});
311

4-
export type { };
12+
type ItemBody = Prisma.ItemGetPayload<typeof itemBody>;
13+
14+
const listBody = Prisma.validator<Prisma.ListArgs>()({
15+
select: {
16+
name: true
17+
}
18+
});
19+
type ListBody = Prisma.ListGetPayload<typeof listBody>;
20+
21+
export type { ItemBody, ListBody };

Diff for: utils/constants.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const HTTP_ERROR_MESSAGES = {
2+
400: "Invalid body content",
3+
401: "You are not signed in",
4+
403: "You do not have permission to do this operation",
5+
404: "The requested roussource was not found",
6+
405: "Method not allowed on this route",
7+
409: "The roussource that you have tried to create already exists"
8+
};
9+
10+
export { HTTP_ERROR_MESSAGES };

Diff for: utils/helpers.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type { NextApiRequest } from "next";
2+
import { getSession } from "next-auth/react";
3+
import { HTTP_ERROR_MESSAGES } from "utils/constants";
4+
import { UnauthorizedException } from "next-api-decorators";
5+
6+
const validateString = (str: string | undefined | null | string[]) => {
7+
if (!str || str == undefined || str == "") return false;
8+
return true;
9+
};
10+
11+
const getUser = async (req: NextApiRequest) => {
12+
const session = await getSession({ req });
13+
const user = session?.user;
14+
if (!session || !user || user == undefined)
15+
throw new UnauthorizedException(HTTP_ERROR_MESSAGES[401]);
16+
return user;
17+
};
18+
19+
export { validateString, getUser };

0 commit comments

Comments
 (0)