mirror of
https://github.com/hknsh/project-knedita.git
synced 2024-11-28 17:41:15 +00:00
Added ESLint and Prettier, added module resolvers, tests not working by now.
This commit is contained in:
parent
fc7ede917c
commit
e11771a62b
77 changed files with 1534 additions and 1584 deletions
2
.eslintignore
Normal file
2
.eslintignore
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules
|
||||||
|
dist
|
18
.eslintrc.json
Normal file
18
.eslintrc.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"es2021": true,
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": "standard-with-typescript",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": "latest",
|
||||||
|
"sourceType": "module",
|
||||||
|
"project": [
|
||||||
|
"./tsconfig.json"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"@typescript-eslint/no-misused-promises": "off",
|
||||||
|
"@typescript-eslint/explicit-function-return-type": 1
|
||||||
|
}
|
||||||
|
}
|
8
.prettierrc
Normal file
8
.prettierrc
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"semi": false,
|
||||||
|
"singleQuote": true,
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"useTabs": false,
|
||||||
|
"endOfLine": "lf",
|
||||||
|
"tabWidth": 2
|
||||||
|
}
|
33
.swcrc
33
.swcrc
|
@ -1,20 +1,17 @@
|
||||||
{
|
{
|
||||||
"jsc": {
|
"jsc": {
|
||||||
"parser": {
|
"parser": {
|
||||||
"syntax": "typescript",
|
"syntax": "typescript",
|
||||||
"tsx": false,
|
"tsx": false,
|
||||||
"decorators": true,
|
"decorators": true,
|
||||||
"dynamicImport": true
|
"dynamicImport": true
|
||||||
},
|
|
||||||
"target": "es2020",
|
|
||||||
"baseUrl": "./"
|
|
||||||
},
|
},
|
||||||
"exclude": [
|
"target": "es2020",
|
||||||
"@types/",
|
"baseUrl": "./"
|
||||||
"interfaces/"
|
},
|
||||||
],
|
"exclude": ["@types/", "interfaces/"],
|
||||||
"module": {
|
"module": {
|
||||||
"type": "commonjs"
|
"type": "commonjs"
|
||||||
},
|
},
|
||||||
"minify": true
|
"minify": true
|
||||||
}
|
}
|
||||||
|
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"json.schemaDownload.enable": true
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
# Project Knedita
|
# Project Knedita
|
||||||
|
|
||||||
An open-source social media.
|
An open-source social media.
|
||||||
|
@ -21,7 +20,6 @@ An open-source social media.
|
||||||
- Image compression ✅
|
- Image compression ✅
|
||||||
- Following/unfollowing features ✅
|
- Following/unfollowing features ✅
|
||||||
- Like posts ✅
|
- Like posts ✅
|
||||||
- Probably pinned posts
|
|
||||||
- Authentication ✅
|
- Authentication ✅
|
||||||
- Add more verification (like, if the password is too short) ✅
|
- Add more verification (like, if the password is too short) ✅
|
||||||
- Set display name ✅
|
- Set display name ✅
|
||||||
|
|
|
@ -11,7 +11,7 @@ services:
|
||||||
- .env
|
- .env
|
||||||
volumes:
|
volumes:
|
||||||
- postgres:/var/lib/postgresql/data
|
- postgres:/var/lib/postgresql/data
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:alpine
|
image: redis:alpine
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
@ -24,4 +24,4 @@ services:
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
postgres:
|
postgres:
|
||||||
name: backend-db
|
name: backend-db
|
||||||
|
|
|
@ -31,7 +31,7 @@ services:
|
||||||
- .env
|
- .env
|
||||||
volumes:
|
volumes:
|
||||||
- postgres:/var/lib/postgresql/data
|
- postgres:/var/lib/postgresql/data
|
||||||
|
|
||||||
localstack:
|
localstack:
|
||||||
image: localstack/localstack
|
image: localstack/localstack
|
||||||
container_name: localstack_main
|
container_name: localstack_main
|
||||||
|
@ -45,7 +45,7 @@ services:
|
||||||
- .env
|
- .env
|
||||||
volumes:
|
volumes:
|
||||||
- localstack:/data
|
- localstack:/data
|
||||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
- '/var/run/docker.sock:/var/run/docker.sock'
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:alpine
|
image: redis:alpine
|
||||||
|
@ -62,4 +62,4 @@ volumes:
|
||||||
name: backend-db
|
name: backend-db
|
||||||
redis:
|
redis:
|
||||||
driver: local
|
driver: local
|
||||||
localstack:
|
localstack:
|
||||||
|
|
2109
package-lock.json
generated
2109
package-lock.json
generated
File diff suppressed because it is too large
Load diff
17
package.json
17
package.json
|
@ -4,11 +4,12 @@
|
||||||
"description": "A social media",
|
"description": "A social media",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "swc src -d dist",
|
"build": "swc src -d dist",
|
||||||
"dev:start": "ts-node-dev --transpile-only --respawn src/server.ts",
|
"dev:start": "ts-node-dev -r tsconfig-paths/register --transpile-only --respawn src/server.ts",
|
||||||
"docker": "docker compose up -d",
|
"docker": "docker compose up -d",
|
||||||
"docker:build": "docker build -t api . && docker compose up -d",
|
"docker:build": "docker build -t api . && docker compose up -d",
|
||||||
"docker:db": "docker compose -f docker-compose.db.yml up -d",
|
"docker:db": "docker compose -f docker-compose.db.yml up -d",
|
||||||
"docker:seed": "docker exec -it api npm run prisma:seed",
|
"docker:seed": "docker exec -it api npm run prisma:seed",
|
||||||
|
"lint": "eslint --ignore-path .eslintignore --ext .js,.ts .",
|
||||||
"migrate:dev": "prisma migrate dev",
|
"migrate:dev": "prisma migrate dev",
|
||||||
"migrate:dev:create": "prisma migrate dev --create-only",
|
"migrate:dev:create": "prisma migrate dev --create-only",
|
||||||
"migrate:reset": "prisma migrate reset",
|
"migrate:reset": "prisma migrate reset",
|
||||||
|
@ -43,16 +44,24 @@
|
||||||
"@types/node": "^20.3.1",
|
"@types/node": "^20.3.1",
|
||||||
"@types/supertest": "^2.0.12",
|
"@types/supertest": "^2.0.12",
|
||||||
"@types/validator": "^13.7.17",
|
"@types/validator": "^13.7.17",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||||
|
"@typescript-eslint/parser": "^5.62.0",
|
||||||
|
"eslint": "^8.46.0",
|
||||||
|
"eslint-config-prettier": "^8.9.0",
|
||||||
|
"eslint-config-standard-with-typescript": "^37.0.0",
|
||||||
|
"eslint-plugin-import": "^2.28.0",
|
||||||
|
"eslint-plugin-n": "^16.0.1",
|
||||||
|
"eslint-plugin-promise": "^6.1.1",
|
||||||
"jest": "^29.5.0",
|
"jest": "^29.5.0",
|
||||||
"nodemon": "^3.0.1",
|
"nodemon": "^3.0.1",
|
||||||
"pm2": "^4.2.3",
|
"pm2": "^4.2.3",
|
||||||
|
"prettier": "^3.0.0",
|
||||||
"prisma": "^5.0.0",
|
"prisma": "^5.0.0",
|
||||||
"supertest": "^6.3.3",
|
"supertest": "^6.3.3",
|
||||||
"ts-jest": "^29.1.0",
|
"ts-jest": "^29.1.0",
|
||||||
"ts-node-dev": "^2.0.0",
|
"ts-node-dev": "^2.0.0",
|
||||||
"ts-standard": "^12.0.2",
|
"tsconfig-paths": "^4.2.0",
|
||||||
"typescript": "^5.1.3"
|
"typescript": "^5.1.6"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "^5.0.0",
|
"@prisma/client": "^5.0.0",
|
||||||
|
|
|
@ -45,6 +45,8 @@ model PostLike {
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// I should join these two up? Yeah, but I will not do it since it didn't work on the first time.
|
||||||
|
|
||||||
model CommentLike {
|
model CommentLike {
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
commentId String
|
commentId String
|
||||||
|
|
|
@ -4,6 +4,8 @@ const redisPassword = process.env.REDIS_PASSWORD ?? ''
|
||||||
const redisHost = process.env.REDIS_HOST ?? ''
|
const redisHost = process.env.REDIS_HOST ?? ''
|
||||||
const redisPort = process.env.REDIS_PORT ?? ''
|
const redisPort = process.env.REDIS_PORT ?? ''
|
||||||
|
|
||||||
const redis = new RedisClient(`redis://:${redisPassword}@${redisHost}:${redisPort}/0`)
|
const redis = new RedisClient(
|
||||||
|
`redis://:${redisPassword}@${redisHost}:${redisPort}/0`
|
||||||
|
)
|
||||||
|
|
||||||
export default redis
|
export default redis
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import multer from 'multer'
|
import multer from 'multer'
|
||||||
import { Request } from 'express'
|
import { type Request } from 'express'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import s3 from '../clients/s3-client'
|
import s3 from 'clients/s3-client'
|
||||||
import multerS3 from 'multer-s3'
|
import multerS3 from 'multer-s3'
|
||||||
|
|
||||||
const tempFolder = path.resolve(__dirname, '..', '..', 'temp', 'uploads')
|
const tempFolder = path.resolve(__dirname, '..', '..', 'temp', 'uploads')
|
||||||
|
@ -18,7 +18,7 @@ const storageTypes = {
|
||||||
const fileName: string = `${folder}/${req.user!.id}.webp`
|
const fileName: string = `${folder}/${req.user!.id}.webp`
|
||||||
|
|
||||||
callback(null, fileName)
|
callback(null, fileName)
|
||||||
}
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
s3: multerS3({
|
s3: multerS3({
|
||||||
|
@ -37,21 +37,22 @@ const storageTypes = {
|
||||||
|
|
||||||
const fileName: string = `${folder}/${req.user!.id}.jpg`
|
const fileName: string = `${folder}/${req.user!.id}.jpg`
|
||||||
callback(null, fileName)
|
callback(null, fileName)
|
||||||
}
|
},
|
||||||
})
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
const multerConfig = {
|
const multerConfig = {
|
||||||
dest: tempFolder,
|
dest: tempFolder,
|
||||||
storage: storageTypes.s3,
|
storage: storageTypes.s3,
|
||||||
limits: {
|
limits: {
|
||||||
fileSize: 15 * 1024 * 1024 // 1mb
|
fileSize: 15 * 1024 * 1024, // 1mb
|
||||||
},
|
},
|
||||||
fileFilter: (req: Request, file: Express.Multer.File, callback: multer.FileFilterCallback) => {
|
fileFilter: (
|
||||||
const allowedMimes = [
|
req: Request,
|
||||||
'image/jpeg',
|
file: Express.Multer.File,
|
||||||
'image/png'
|
callback: multer.FileFilterCallback,
|
||||||
]
|
) => {
|
||||||
|
const allowedMimes = ['image/jpeg', 'image/png']
|
||||||
|
|
||||||
if (allowedMimes.includes(file.mimetype)) {
|
if (allowedMimes.includes(file.mimetype)) {
|
||||||
callback(null, true)
|
callback(null, true)
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
||||||
import { Router } from 'express'
|
import { Router } from 'express'
|
||||||
|
|
||||||
// Controllers
|
// Controllers
|
||||||
import comments from './comments'
|
import comments from './comments'
|
||||||
|
|
||||||
// Middlewares
|
// Middlewares
|
||||||
import authenticated from '../middlewares/authenticated'
|
import authenticated from 'middlewares/authenticated'
|
||||||
|
|
||||||
const commentsRouter = Router()
|
const commentsRouter = Router()
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,26 @@
|
||||||
import comment from '../../services/comments'
|
import comment from 'services/comments'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function commentCreateController (req: Request, res: Response): Promise<void> {
|
async function commentCreateController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const { content, postId } = req.body
|
const { content, postId } = req.body
|
||||||
const id = req.user?.id ?? ''
|
const id = req.user?.id ?? ''
|
||||||
|
|
||||||
if (postId === undefined) {
|
if (postId === undefined) {
|
||||||
return badRequest(res, 'Expected post id')
|
badRequest(res, 'Expected post id'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (content === undefined) {
|
if (content === undefined) {
|
||||||
return badRequest(res, 'Expected comment content')
|
badRequest(res, 'Expected comment content'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await comment.create(postId, content, id)
|
const result = await comment.create(postId, content, id)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
import comment from '../../services/comments'
|
import comment from 'services/comments'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function commentDeleteController (req: Request, res: Response): Promise<void> {
|
async function commentDeleteController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const { commentId } = req.body
|
const { commentId } = req.body
|
||||||
const id = req.user?.id ?? ''
|
const id = req.user?.id ?? ''
|
||||||
|
|
||||||
if (commentId === undefined) {
|
if (commentId === undefined) {
|
||||||
return badRequest(res, 'Expected comment id')
|
badRequest(res, 'Expected comment id'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await comment.delete(commentId, id)
|
const result = await comment.delete(commentId, id)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
import comment from '../../services/comments'
|
import comment from 'services/comments'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function commentFetchController (req: Request, res: Response): Promise<void> {
|
async function commentFetchController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const commentId = req.query.id as string
|
const commentId = req.query.id as string
|
||||||
|
|
||||||
if (commentId === undefined) {
|
if (commentId === undefined) {
|
||||||
return badRequest(res, 'Expected comment id')
|
badRequest(res, 'Expected comment id'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await comment.fetch(commentId)
|
const result = await comment.fetch(commentId)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
import comment from '../../services/comments'
|
import comment from 'services/comments'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function commentFetchLikesController (req: Request, res: Response): Promise<void> {
|
async function commentFetchLikesController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const commentId = req.query.id as string
|
const commentId = req.query.id as string
|
||||||
|
|
||||||
if (commentId === undefined) {
|
if (commentId === undefined) {
|
||||||
return badRequest(res, 'Expected comment id')
|
badRequest(res, 'Expected comment id'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await comment.fetchLikes(commentId)
|
const result = await comment.fetchLikes(commentId)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,23 +1,26 @@
|
||||||
import comment from '../../services/comments'
|
import comment from 'services/comments'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function commentUpdateController (req: Request, res: Response): Promise<void> {
|
async function commentUpdateController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const { commentId, content } = req.body
|
const { commentId, content } = req.body
|
||||||
const id = req.user?.id ?? ''
|
const id = req.user?.id ?? ''
|
||||||
|
|
||||||
if (commentId === undefined) {
|
if (commentId === undefined) {
|
||||||
return badRequest(res, 'Expected comment content')
|
badRequest(res, 'Expected comment content'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (content === undefined) {
|
if (content === undefined) {
|
||||||
return badRequest(res, 'Expected content to update')
|
badRequest(res, 'Expected content to update'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await comment.update(content, id, commentId)
|
const result = await comment.update(content, id, commentId)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
||||||
import { Router } from 'express'
|
import { Router } from 'express'
|
||||||
|
|
||||||
// Controllers
|
// Controllers
|
||||||
import post from './posts'
|
import post from './posts'
|
||||||
|
|
||||||
// Middlewares
|
// Middlewares
|
||||||
import authenticated from '../middlewares/authenticated'
|
import authenticated from 'middlewares/authenticated'
|
||||||
|
|
||||||
const postsRouter = Router()
|
const postsRouter = Router()
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
import post from '../../services/posts'
|
import post from 'services/posts'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function postCreateController (req: Request, res: Response): Promise<void> {
|
async function postCreateController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const { content } = req.body
|
const { content } = req.body
|
||||||
const id: string = req.user?.id ?? ''
|
const id: string = req.user?.id ?? ''
|
||||||
|
|
||||||
if (content === undefined) {
|
if (content === undefined) {
|
||||||
return badRequest(res, 'Expected post content')
|
badRequest(res, 'Expected post content'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await post.create(content, id)
|
const result = await post.create(content, id)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
import post from '../../services/posts'
|
import post from 'services/posts'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function postDeleteController (req: Request, res: Response): Promise<void> {
|
async function postDeleteController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const userId = req.user?.id ?? ''
|
const userId = req.user?.id ?? ''
|
||||||
const postId = req.body.postId
|
const postId = req.body.postId
|
||||||
|
|
||||||
const result = await post.delete(postId, userId)
|
const result = await post.delete(postId, userId)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
import post from '../../services/posts'
|
import post from 'services/posts'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function postFetchInfoController (req: Request, res: Response): Promise<void> {
|
async function postFetchInfoController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const id = req.query.id as string
|
const id = req.query.id as string
|
||||||
|
|
||||||
if (id === undefined) {
|
if (id === undefined) {
|
||||||
return badRequest(res, 'Missing post id')
|
badRequest(res, 'Missing post id'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await post.fetch(id)
|
const result = await post.fetch(id)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
import post from '../../services/posts'
|
import post from 'services/posts'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function postFetchLikesController (req: Request, res: Response): Promise<void> {
|
async function postFetchLikesController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const id = req.query.id as string
|
const id = req.query.id as string
|
||||||
|
|
||||||
if (id === undefined) {
|
if (id === undefined) {
|
||||||
return badRequest(res, 'Missing post id')
|
badRequest(res, 'Missing post id'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await post.fetchLikes(id)
|
const result = await post.fetchLikes(id)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
import post from '../../services/posts'
|
import post from 'services/posts'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function postUpdateController (req: Request, res: Response): Promise<void> {
|
async function postUpdateController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const { postId, content } = req.body
|
const { postId, content } = req.body
|
||||||
const userId = req.user?.id ?? ''
|
const userId = req.user?.id ?? ''
|
||||||
|
|
||||||
const result = await post.update(postId, content, userId)
|
const result = await post.update(postId, content, userId)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
||||||
import { Router } from 'express'
|
import { Router } from 'express'
|
||||||
|
|
||||||
// Controllers
|
// Controllers
|
||||||
import user from './users'
|
import user from './users'
|
||||||
|
|
||||||
// Middlewares
|
// Middlewares
|
||||||
import authenticated from '../middlewares/authenticated'
|
import authenticated from 'middlewares/authenticated'
|
||||||
import uploadFile from '../middlewares/upload-image'
|
import uploadFile from 'middlewares/upload-image'
|
||||||
|
|
||||||
const usersRouter = Router()
|
const usersRouter = Router()
|
||||||
|
|
||||||
|
@ -24,7 +23,12 @@ usersRouter.post('/like-post', authenticated, user.likePost)
|
||||||
usersRouter.post('/signup', user.signup)
|
usersRouter.post('/signup', user.signup)
|
||||||
|
|
||||||
// PUT
|
// PUT
|
||||||
usersRouter.put('/profile-picture/upload', authenticated, uploadFile, user.uploadPicture)
|
usersRouter.put(
|
||||||
|
'/profile-picture/upload',
|
||||||
|
authenticated,
|
||||||
|
uploadFile,
|
||||||
|
user.uploadPicture
|
||||||
|
)
|
||||||
usersRouter.put('/update', authenticated, user.update)
|
usersRouter.put('/update', authenticated, user.update)
|
||||||
|
|
||||||
export default usersRouter
|
export default usersRouter
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import user from '../../services/users'
|
import user from 'services/users'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function userAuthController (req: Request, res: Response): Promise<void> {
|
async function userAuthController (req: Request, res: Response): Promise<void> {
|
||||||
const { email, password } = req.body
|
const { email, password } = req.body
|
||||||
|
|
||||||
const result = await user.auth(email, password)
|
const result = await user.auth({ email, password })
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
import user from '../../services/users'
|
import user from 'services/users'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function userDeleteController (req: Request, res: Response): Promise<void> {
|
async function userDeleteController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const userId = req.user?.id ?? ''
|
const userId = req.user?.id ?? ''
|
||||||
const result = await user.delete(userId)
|
const result = await user.delete(userId)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
import user from '../../services/users'
|
import user from 'services/users'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function userFetchInfoController (req: Request, res: Response): Promise<void> {
|
async function userFetchInfoController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const username = req.query.u as string
|
const username = req.query.u as string
|
||||||
|
|
||||||
if (username === undefined) {
|
if (username === undefined) {
|
||||||
return badRequest(res, 'Missing username')
|
badRequest(res, 'Missing username'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await user.fetchInfo(username.toLowerCase())
|
const result = await user.fetchInfo(username.toLowerCase())
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import user from '../../services/users'
|
import user from 'services/users'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function userFetchPostsController (req: Request, res: Response): Promise<void> {
|
async function userFetchPostsController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const username = req.query.u as string
|
const username = req.query.u as string
|
||||||
|
|
||||||
if (username === undefined) {
|
if (username === undefined) {
|
||||||
return badRequest(res, 'Missing username')
|
badRequest(res, 'Missing username'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await user.fetchPosts(username)
|
const result = await user.fetchPosts(username)
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
import user from '../../services/users'
|
import user from 'services/users'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function userFollowController (req: Request, res: Response): Promise<void> {
|
async function userFollowController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const userId = req.user?.id ?? ''
|
const userId = req.user?.id ?? ''
|
||||||
const { userToFollow } = req.body
|
const { userToFollow } = req.body
|
||||||
|
|
||||||
const result = await user.follow(userId, userToFollow)
|
const result = await user.follow(userId, userToFollow)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
import user from '../../services/users'
|
import user from 'services/users'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function userLikeCommentController (req: Request, res: Response): Promise<void> {
|
async function userLikeCommentController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const userId = req.user?.id ?? ''
|
const userId = req.user?.id ?? ''
|
||||||
const { commentId, postId } = req.body
|
const { commentId } = req.body
|
||||||
|
|
||||||
const result = await user.likeComment(postId, commentId, userId)
|
const result = await user.likeComment(commentId, userId)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
import user from '../../services/users'
|
import user from 'services/users'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function userLikePostController (req: Request, res: Response): Promise<void> {
|
async function userLikePostController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const userId = req.user?.id ?? ''
|
const userId = req.user?.id ?? ''
|
||||||
const { postId } = req.body
|
const { postId } = req.body
|
||||||
|
|
||||||
const result = await user.likePost(postId, userId)
|
const result = await user.likePost(postId, userId)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import user from '../../services/users'
|
import user from 'services/users'
|
||||||
import { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function userSearchController (req: Request, res: Response): Promise<void> {
|
async function userSearchController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const username = req.query.u as string
|
const username = req.query.u as string
|
||||||
|
|
||||||
if (username === undefined) {
|
if (username === undefined) {
|
||||||
return badRequest(res, 'Missing username')
|
badRequest(res, 'Missing username'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await user.searchUser(username)
|
const result = await user.searchUser(username)
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
import user from '../../services/users'
|
import user from 'services/users'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function userSignupController (req: Request, res: Response): Promise<void> {
|
async function userSignupController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const { username, email, password } = req.body
|
const { username, email, password } = req.body
|
||||||
|
|
||||||
const result = await user.signup(username, email, password)
|
const result = await user.signup({ username, email, password })
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
import user from '../../services/users'
|
import user from 'services/users'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
async function userUpdateController (req: Request, res: Response): Promise<void> {
|
async function userUpdateController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
const { email, displayName, username } = req.body
|
const { email, displayName, username } = req.body
|
||||||
const id = req.user?.id ?? ''
|
const id = req.user?.id ?? ''
|
||||||
|
|
||||||
const result = await user.update({ id, email, displayName, username })
|
const result = await user.update({ id, email, displayName, username })
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||||
import user from '../../services/users'
|
import user from 'services/users'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
let url
|
let url
|
||||||
|
|
||||||
async function userUploadPictureController (req: Request, res: Response): Promise<void> {
|
async function userUploadPictureController (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
if (req.file === undefined) {
|
if (req.file === undefined) {
|
||||||
return badRequest(res, 'Expected a JPG or PNG file')
|
badRequest(res, 'Expected a JPG or PNG file'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
const userId = req.user?.id ?? ''
|
const userId = req.user?.id ?? ''
|
||||||
|
@ -23,7 +26,7 @@ async function userUploadPictureController (req: Request, res: Response): Promis
|
||||||
const result = await user.uploadPicture(userId, url)
|
const result = await user.uploadPicture(userId, url)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
badRequest(res, result.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result)
|
res.json(result)
|
||||||
|
|
|
@ -2,8 +2,8 @@ interface userPayload {
|
||||||
id?: string
|
id?: string
|
||||||
displayName?: string | null
|
displayName?: string | null
|
||||||
username?: string
|
username?: string
|
||||||
password?: string
|
|
||||||
email?: string
|
email?: string
|
||||||
|
password?: string
|
||||||
token?: string
|
token?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,26 @@
|
||||||
import sharp from 'sharp'
|
import sharp from 'sharp'
|
||||||
import s3 from '../clients/s3-client'
|
import s3 from 'clients/s3-client'
|
||||||
import { GetObjectCommand, PutObjectCommand } from '@aws-sdk/client-s3'
|
import { GetObjectCommand, PutObjectCommand } from '@aws-sdk/client-s3'
|
||||||
|
|
||||||
export default async function compressImage (imageName: string): Promise<Error | Object > {
|
export default async function compressImage (
|
||||||
|
imageName: string,
|
||||||
|
isProfilePicture: string
|
||||||
|
): Promise<Error | Record<never, never>> {
|
||||||
// Get file from s3
|
// Get file from s3
|
||||||
const { Body } = await s3.send(new GetObjectCommand({
|
const { Body } = await s3.send(
|
||||||
Bucket: process.env.AWS_BUCKET ?? '',
|
new GetObjectCommand({
|
||||||
Key: imageName
|
Bucket: process.env.AWS_BUCKET ?? '',
|
||||||
}))
|
Key: imageName
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
const imageBuffer = await Body?.transformToByteArray()
|
const imageBuffer = await Body?.transformToByteArray()
|
||||||
|
|
||||||
const compressedImageBuffer = await sharp(imageBuffer)
|
const compressedImageBuffer = await sharp(imageBuffer)
|
||||||
|
.resize(
|
||||||
|
isProfilePicture === 'true' ? 200 : undefined,
|
||||||
|
isProfilePicture === 'true' ? 200 : undefined
|
||||||
|
)
|
||||||
.jpeg({ quality: 65 })
|
.jpeg({ quality: 65 })
|
||||||
.toBuffer()
|
.toBuffer()
|
||||||
|
|
||||||
|
|
29
src/lib/create-notification.ts
Normal file
29
src/lib/create-notification.ts
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import { type NotificationType } from '@prisma/client'
|
||||||
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
|
export default async function createNotification (
|
||||||
|
fromUserId: string,
|
||||||
|
toUserId: string,
|
||||||
|
content: string,
|
||||||
|
type: NotificationType
|
||||||
|
): Promise<Record<never, never> | Error> {
|
||||||
|
await prisma.notifications.create({
|
||||||
|
data: {
|
||||||
|
type,
|
||||||
|
fromUserId,
|
||||||
|
toUserId,
|
||||||
|
content
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
fromUser: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
displayName: true,
|
||||||
|
username: true,
|
||||||
|
profileImage: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return {}
|
||||||
|
}
|
|
@ -1,6 +1,10 @@
|
||||||
import { Response } from 'express'
|
import { type Response } from 'express'
|
||||||
|
|
||||||
const sendErrorResponse = (res: Response, status: number, message: string): void => {
|
const sendErrorResponse = (
|
||||||
|
res: Response,
|
||||||
|
status: number,
|
||||||
|
message: string
|
||||||
|
): void => {
|
||||||
res.status(status).json({ error: message })
|
res.status(status).json({ error: message })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +20,9 @@ export const forbidden = (res: Response, message = 'Forbidden'): void => {
|
||||||
sendErrorResponse(res, 403, message)
|
sendErrorResponse(res, 403, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const internalServerError = (res: Response, message = 'Internal Server Error'): void => {
|
export const internalServerError = (
|
||||||
|
res: Response,
|
||||||
|
message = 'Internal Server Error'
|
||||||
|
): void => {
|
||||||
sendErrorResponse(res, 500, message)
|
sendErrorResponse(res, 500, message)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,38 @@
|
||||||
import { verify } from 'jsonwebtoken'
|
import { verify } from 'jsonwebtoken'
|
||||||
import prisma from '../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
import type { Response, Request, NextFunction } from 'express'
|
import type { Response, Request, NextFunction } from 'express'
|
||||||
import jwtPayload from '../interfaces/jwt'
|
import type jwtPayload from 'interfaces/jwt'
|
||||||
import { unauthorized } from '../lib/http-errors'
|
import { unauthorized } from 'lib/http-errors'
|
||||||
|
|
||||||
async function authenticated (req: Request, res: Response, next: NextFunction): Promise<void> {
|
async function authenticated (
|
||||||
if (req.headers.authorization === undefined || req.headers.authorization.length === 0) {
|
req: Request,
|
||||||
return unauthorized(res, 'Missing token')
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
): Promise<void> {
|
||||||
|
if (
|
||||||
|
req.headers.authorization === undefined ||
|
||||||
|
req.headers.authorization.length === 0
|
||||||
|
) {
|
||||||
|
unauthorized(res, 'Missing token'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
const token = req.headers.authorization.split(' ')[1]
|
const token = req.headers.authorization.split(' ')[1]
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const decoded = await new Promise<jwtPayload | undefined>((resolve, reject) => {
|
const decoded = await new Promise<jwtPayload | undefined>(
|
||||||
verify(token, process.env.JWT_ACCESS_SECRET ?? '', (error, decoded) => {
|
(resolve, reject) => {
|
||||||
if (error != null) {
|
verify(token, process.env.JWT_ACCESS_SECRET ?? '', (error, decoded) => {
|
||||||
reject(error)
|
if (error != null) {
|
||||||
} else {
|
reject(error)
|
||||||
resolve(decoded as jwtPayload)
|
} else {
|
||||||
}
|
resolve(decoded as jwtPayload)
|
||||||
})
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if (decoded == null) {
|
if (decoded == null) {
|
||||||
return unauthorized(res, 'Invalid token')
|
unauthorized(res, 'Invalid token'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await prisma.user.findFirst({
|
const user = await prisma.user.findFirst({
|
||||||
|
@ -33,12 +42,12 @@ async function authenticated (req: Request, res: Response, next: NextFunction):
|
||||||
})
|
})
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return unauthorized(res, 'User does not exists')
|
unauthorized(res, 'User does not exists'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
req.user = decoded
|
req.user = decoded
|
||||||
|
|
||||||
return next()
|
next()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
unauthorized(res, `JWT Error: ${(error as Error).message}`)
|
unauthorized(res, `JWT Error: ${(error as Error).message}`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import rateLimit from 'express-rate-limit'
|
import rateLimit from 'express-rate-limit'
|
||||||
import RedisStore from 'rate-limit-redis'
|
import RedisStore from 'rate-limit-redis'
|
||||||
import redis from '../clients/redis-client'
|
import redis from 'clients/redis-client'
|
||||||
|
|
||||||
let maxConnections
|
let maxConnections
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,30 @@
|
||||||
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
||||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
||||||
import type { Response, Request, NextFunction } from 'express'
|
import type { Response, Request, NextFunction } from 'express'
|
||||||
import multer from 'multer'
|
import multer from 'multer'
|
||||||
import multerConfig from '../config/multer'
|
import multerConfig from 'config/multer'
|
||||||
import compressImage from '../lib/compress-image'
|
import compressImage from 'lib/compress-image'
|
||||||
import { badRequest } from '../lib/http-errors'
|
import { badRequest } from 'lib/http-errors'
|
||||||
|
|
||||||
function uploadImage (req: Request, res: Response, next: NextFunction) {
|
function uploadImage (req: Request, res: Response, next: NextFunction) {
|
||||||
const upload = multer(multerConfig).single('image')
|
const upload = multer(multerConfig).single('image')
|
||||||
|
|
||||||
upload(req, res, async (cb: multer.MulterError | Error | any) => {
|
upload(req, res, async (cb: multer.MulterError | Error | any) => {
|
||||||
if (req.user == null) {
|
if (req.user == null) {
|
||||||
return badRequest(res, 'You must be logged in to upload a profile picture')
|
badRequest(
|
||||||
|
res,
|
||||||
|
'You must be logged in to upload a profile picture'
|
||||||
|
); return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cb instanceof multer.MulterError || cb instanceof Error) {
|
if (cb instanceof multer.MulterError || cb instanceof Error) {
|
||||||
return badRequest(res, cb.message)
|
badRequest(res, cb.message); return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.file === undefined) {
|
if (req.file === undefined) {
|
||||||
return badRequest(res, 'Expected file')
|
badRequest(res, 'Expected file'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ts-expect-error property `key` does not exists in types
|
// @ts-expect-error property `key` does not exists in types
|
||||||
await compressImage(req.file?.key)
|
await compressImage(req.file?.key, req.body.isProfilePicture)
|
||||||
|
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function commentCreateService (postId: string, content: string, authorId: string): Promise<Object | Error> {
|
async function commentCreateService (
|
||||||
|
postId: string,
|
||||||
|
content: string,
|
||||||
|
authorId: string
|
||||||
|
): Promise<Record<string, unknown> | Error> {
|
||||||
const post = await prisma.post.findFirst({
|
const post = await prisma.post.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id: postId
|
id: postId
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function commentDeleteService (commentId: string, authorId: string): Promise<Object | Error> {
|
async function commentDeleteService (
|
||||||
|
commentId: string,
|
||||||
|
authorId: string
|
||||||
|
): Promise<Record<string, unknown> | Error> {
|
||||||
const user = await prisma.user.findFirst({
|
const user = await prisma.user.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id: authorId
|
id: authorId
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function commentFetchService (commentId: string): Promise<Object | Error> {
|
async function commentFetchService (commentId: string): Promise<Record<string, unknown> | Error> {
|
||||||
const comment = await prisma.comments.findFirst({
|
const comment = await prisma.comments.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id: commentId
|
id: commentId
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function commentFetchLikesService (id: string): Promise<Object | Error> {
|
async function commentFetchLikesService (id: string): Promise<unknown | Error> {
|
||||||
const post = await prisma.commentLike.findMany({
|
const post = await prisma.commentLike.findMany({
|
||||||
where: {
|
where: {
|
||||||
commentId: id
|
commentId: id
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function commentUpdateService (content: string, authorId: string, commentId: string): Promise<Object | Error> {
|
async function commentUpdateService (
|
||||||
|
content: string,
|
||||||
|
authorId: string,
|
||||||
|
commentId: string
|
||||||
|
): Promise<Record<string, unknown> | Error> {
|
||||||
const comment = await prisma.comments.findFirst({
|
const comment = await prisma.comments.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id: commentId,
|
id: commentId,
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function postCreateService (content: string, authorId: string): Promise<Object | Error> {
|
async function postCreateService (
|
||||||
|
content: string,
|
||||||
|
authorId: string
|
||||||
|
): Promise<Record<string, unknown> | Error> {
|
||||||
const user = await prisma.user.findFirst({ where: { id: authorId } })
|
const user = await prisma.user.findFirst({ where: { id: authorId } })
|
||||||
|
|
||||||
if (user === null) {
|
if (user === null) {
|
||||||
return new Error('This user doesn\'t exists')
|
return new Error("This user doesn't exists")
|
||||||
}
|
}
|
||||||
|
|
||||||
const post = await prisma.post.create({
|
const post = await prisma.post.create({
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function postDeleteService (postId: string, userId: string): Promise<Object | Error> {
|
async function postDeleteService (
|
||||||
|
postId: string,
|
||||||
|
userId: string
|
||||||
|
): Promise<Record<string, unknown> | Error> {
|
||||||
const post = await prisma.post.findFirst({ where: { id: postId } })
|
const post = await prisma.post.findFirst({ where: { id: postId } })
|
||||||
|
|
||||||
if (post === null) {
|
if (post === null) {
|
||||||
return new Error('Post not found')
|
return new Error('Post not found')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await prisma.user.findFirst({ where: { id: userId } }) === null) {
|
if ((await prisma.user.findFirst({ where: { id: userId } })) === null) {
|
||||||
return new Error('User not found')
|
return new Error('User not found')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function postFetchInfoService (id: string): Promise<Object | Error> {
|
async function postFetchInfoService (id: string): Promise<Record<string, unknown> | Error> {
|
||||||
const post = await prisma.post.findFirst({
|
const post = await prisma.post.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id
|
id
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function postFetchLikesService (id: string): Promise<Object | Error> {
|
async function postFetchLikesService (id: string): Promise<unknown | Error> {
|
||||||
const post = await prisma.postLike.findMany({
|
const post = await prisma.postLike.findMany({
|
||||||
where: {
|
where: {
|
||||||
postId: id
|
postId: id
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function postUpdateService (postId: string, content: string, userId: string): Promise<Object | Error> {
|
async function postUpdateService (
|
||||||
|
postId: string,
|
||||||
|
content: string,
|
||||||
|
userId: string
|
||||||
|
): Promise<Record<string, unknown> | Error> {
|
||||||
const post = await prisma.post.findFirst({ where: { id: postId } })
|
const post = await prisma.post.findFirst({ where: { id: postId } })
|
||||||
|
|
||||||
if (post === null) {
|
if (post === null) {
|
||||||
return new Error('Post not found')
|
return new Error('Post not found')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await prisma.user.findFirst({ where: { id: userId } }) === null) {
|
if ((await prisma.user.findFirst({ where: { id: userId } })) === null) {
|
||||||
return new Error('User not found')
|
return new Error('User not found')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
import * as bcrypt from 'bcrypt'
|
import * as bcrypt from 'bcrypt'
|
||||||
import jsonwebtoken from 'jsonwebtoken'
|
import jsonwebtoken from 'jsonwebtoken'
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
import type userPayload from 'interfaces/user'
|
||||||
|
|
||||||
async function userAuthService (email: string, password: string): Promise<Object | Error> {
|
async function userAuthService ({
|
||||||
|
email,
|
||||||
|
password
|
||||||
|
}: userPayload): Promise<Record<string, unknown> | Error> {
|
||||||
const user = await prisma.user.findFirst({
|
const user = await prisma.user.findFirst({
|
||||||
where: {
|
where: {
|
||||||
email
|
email
|
||||||
|
@ -17,7 +21,10 @@ async function userAuthService (email: string, password: string): Promise<Object
|
||||||
return new Error('Missing fields')
|
return new Error('Missing fields')
|
||||||
}
|
}
|
||||||
|
|
||||||
const validPassword = await bcrypt.compare(password.replace(/ /g, ''), user.password)
|
const validPassword = await bcrypt.compare(
|
||||||
|
password.replace(/ /g, ''),
|
||||||
|
user.password
|
||||||
|
)
|
||||||
|
|
||||||
if (!validPassword) {
|
if (!validPassword) {
|
||||||
return new Error('Invalid email or password')
|
return new Error('Invalid email or password')
|
||||||
|
@ -25,7 +32,11 @@ async function userAuthService (email: string, password: string): Promise<Object
|
||||||
|
|
||||||
const { id } = user
|
const { id } = user
|
||||||
|
|
||||||
const bearer = jsonwebtoken.sign({ id }, process.env.JWT_ACCESS_SECRET ?? '', { expiresIn: '1d' })
|
const bearer = jsonwebtoken.sign(
|
||||||
|
{ id },
|
||||||
|
process.env.JWT_ACCESS_SECRET ?? '',
|
||||||
|
{ expiresIn: '1d' }
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
token: bearer
|
token: bearer
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function userDeleteService (userId: string): Promise<Object | Error> {
|
async function userDeleteService (userId: string): Promise<Record<string, unknown> | Error> {
|
||||||
const user = await prisma.user.findFirst({ where: { id: userId } })
|
const user = await prisma.user.findFirst({ where: { id: userId } })
|
||||||
|
|
||||||
if (user === null) {
|
if (user === null) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function userFetchInfoService (username: string): Promise<Object | Error> {
|
async function userFetchInfoService (username: string): Promise<Record<string, unknown> | Error> {
|
||||||
const user = await prisma.user.findFirst({
|
const user = await prisma.user.findFirst({
|
||||||
where: {
|
where: {
|
||||||
username
|
username
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function userFetchPostsService (username: string): Promise<Object | Error> {
|
async function userFetchPostsService (
|
||||||
|
username: string
|
||||||
|
): Promise<unknown | Error> {
|
||||||
const posts = await prisma.post.findMany({
|
const posts = await prisma.post.findMany({
|
||||||
where: {
|
where: {
|
||||||
author: {
|
author: {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function userFollowService (userId: string, followingUsername: string): Promise<Object | Error> {
|
async function userFollowService (
|
||||||
|
userId: string,
|
||||||
|
followingUsername: string
|
||||||
|
): Promise<Record<string, unknown> | Error> {
|
||||||
if (userId === undefined || followingUsername === undefined) {
|
if (userId === undefined || followingUsername === undefined) {
|
||||||
return new Error('Missing fields')
|
return new Error('Missing fields')
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function userLikeCommentService (postId: string, commentId: string, userId: string): Promise<Object | Error> {
|
async function userLikeCommentService (
|
||||||
|
commentId: string,
|
||||||
|
userId: string
|
||||||
|
): Promise<Record<string, unknown> | Error> {
|
||||||
if (commentId === undefined || userId === undefined) {
|
if (commentId === undefined || userId === undefined) {
|
||||||
return new Error('Missing fields')
|
return new Error('Missing fields')
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function userLikePostService (postId: string, userId: string): Promise<Object | Error> {
|
async function userLikePostService (
|
||||||
|
postId: string,
|
||||||
|
userId: string
|
||||||
|
): Promise<Record<string, unknown> | Error> {
|
||||||
if (postId === undefined || userId === undefined) {
|
if (postId === undefined || userId === undefined) {
|
||||||
return new Error('Missing fields')
|
return new Error('Missing fields')
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function userSearchService (username: string): Promise<Object | Error> {
|
async function userSearchService (username: string): Promise<unknown | Error> {
|
||||||
const users = await prisma.user.findMany({
|
const users = await prisma.user.findMany({
|
||||||
where: {
|
where: {
|
||||||
username: {
|
username: {
|
||||||
|
|
|
@ -1,17 +1,24 @@
|
||||||
import * as bcrypt from 'bcrypt'
|
import * as bcrypt from 'bcrypt'
|
||||||
import validator from 'validator'
|
import validator from 'validator'
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
import type userPayload from 'interfaces/user'
|
||||||
|
|
||||||
const passwordRegex = /^(?=.*[0-9])(?=.*[!@#$%^&*_])[a-zA-Z0-9!@#$%^&*_]{8,}$/
|
const passwordRegex = /^(?=.*[0-9])(?=.*[!@#$%^&*_])[a-zA-Z0-9!@#$%^&*_]{8,}$/
|
||||||
const usernameRegex = /^[a-zA-Z0-9_.]{5,15}$/
|
const usernameRegex = /^[a-zA-Z0-9_.]{5,15}$/
|
||||||
|
|
||||||
async function userSignupService (username: string, email: string, password: string): Promise<Object | Error> {
|
async function userSignupService ({
|
||||||
|
username,
|
||||||
|
email,
|
||||||
|
password
|
||||||
|
}: userPayload): Promise<Record<string, unknown> | Error> {
|
||||||
if (username === undefined || email === undefined || password === undefined) {
|
if (username === undefined || email === undefined || password === undefined) {
|
||||||
return new Error('Missing fields')
|
return new Error('Missing fields')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!passwordRegex.test(password)) {
|
if (!passwordRegex.test(password)) {
|
||||||
return new Error('Password must have at least 8 characters, one number and one special character.')
|
return new Error(
|
||||||
|
'Password must have at least 8 characters, one number and one special character.'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (password.trim().length < 8) {
|
if (password.trim().length < 8) {
|
||||||
|
@ -19,7 +26,9 @@ async function userSignupService (username: string, email: string, password: str
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!usernameRegex.test(username)) {
|
if (!usernameRegex.test(username)) {
|
||||||
return new Error('Username not allowed. Only alphanumerics characters (uppercase and lowercase words), underscore, dots and it must be between 5 and 15 characters')
|
return new Error(
|
||||||
|
'Username not allowed. Only alphanumerics characters (uppercase and lowercase words), underscore, dots and it must be between 5 and 15 characters'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!validator.isEmail(email)) {
|
if (!validator.isEmail(email)) {
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
import userPayload from '../../interfaces/user'
|
import type userPayload from 'interfaces/user'
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function userUpdateService ({ id, email, displayName, username }: userPayload): Promise<Object | Error> {
|
async function userUpdateService ({
|
||||||
|
id,
|
||||||
|
email,
|
||||||
|
displayName,
|
||||||
|
username
|
||||||
|
}: userPayload): Promise<Record<string, unknown> | Error> {
|
||||||
const user = await prisma.user.findFirst({ where: { id } })
|
const user = await prisma.user.findFirst({ where: { id } })
|
||||||
|
|
||||||
if (user === null) {
|
if (user === null) {
|
||||||
|
@ -13,14 +18,14 @@ async function userUpdateService ({ id, email, displayName, username }: userPayl
|
||||||
|
|
||||||
if (email !== undefined && email.trim() !== user.email) {
|
if (email !== undefined && email.trim() !== user.email) {
|
||||||
const existingUser = await prisma.user.findFirst({ where: { email } })
|
const existingUser = await prisma.user.findFirst({ where: { email } })
|
||||||
if ((existingUser != null) && existingUser.email !== user.email) {
|
if (existingUser != null && existingUser.email !== user.email) {
|
||||||
return new Error('Email already in use')
|
return new Error('Email already in use')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (username !== undefined && username.trim() !== user.username) {
|
if (username !== undefined && username.trim() !== user.username) {
|
||||||
const existingUser = await prisma.user.findFirst({ where: { username } })
|
const existingUser = await prisma.user.findFirst({ where: { username } })
|
||||||
if ((existingUser != null) && existingUser.username !== user.username) {
|
if (existingUser != null && existingUser.username !== user.username) {
|
||||||
return new Error('Username already in use')
|
return new Error('Username already in use')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from 'clients/prisma-client'
|
||||||
|
|
||||||
async function userUploadPictureService (authorId: string, url: string): Promise<Object | Error> {
|
async function userUploadPictureService (
|
||||||
|
authorId: string,
|
||||||
|
url: string
|
||||||
|
): Promise<Record<string, unknown> | Error> {
|
||||||
const user = await prisma.user.findFirst({ where: { id: authorId } })
|
const user = await prisma.user.findFirst({ where: { id: authorId } })
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import app from '../../app'
|
||||||
import request from 'supertest'
|
import request from 'supertest'
|
||||||
import signUpNewUser from '../utils/create-user'
|
import signUpNewUser from '../utils/create-user'
|
||||||
import deleteUser from '../utils/delete-user'
|
import deleteUser from '../utils/delete-user'
|
||||||
import userPayload from '../../interfaces/user'
|
import type userPayload from '../../interfaces/user'
|
||||||
|
|
||||||
let user: userPayload
|
let user: userPayload
|
||||||
|
|
||||||
|
@ -16,17 +16,23 @@ describe('POST /post/create', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should respond with 200 status code if the user send the token and the content', async () => {
|
it('should respond with 200 status code if the user send the token and the content', async () => {
|
||||||
const response = await request(app).post('/post/create').send({
|
const response = await request(app)
|
||||||
content: 'Hello world'
|
.post('/post/create')
|
||||||
}).set('Authorization', `Bearer ${user.token ?? ''}`).expect(200)
|
.send({
|
||||||
|
content: 'Hello world'
|
||||||
|
})
|
||||||
|
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||||
|
.expect(200)
|
||||||
|
|
||||||
expect(response.body).toEqual(expect.objectContaining({
|
expect(response.body).toEqual(
|
||||||
id: expect.any(String),
|
expect.objectContaining({
|
||||||
content: expect.any(String),
|
id: expect.any(String),
|
||||||
authorId: expect.any(String),
|
content: expect.any(String),
|
||||||
createdAt: expect.any(String),
|
authorId: expect.any(String),
|
||||||
updatedAt: expect.any(String)
|
createdAt: expect.any(String),
|
||||||
}))
|
updatedAt: expect.any(String)
|
||||||
|
})
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should respond with 400 status code if the user send no token', async () => {
|
it('should respond with 400 status code if the user send no token', async () => {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import app from '../../app'
|
||||||
import request from 'supertest'
|
import request from 'supertest'
|
||||||
import signUpNewUser from '../utils/create-user'
|
import signUpNewUser from '../utils/create-user'
|
||||||
import deleteUser from '../utils/delete-user'
|
import deleteUser from '../utils/delete-user'
|
||||||
import userPayload from '../../interfaces/user'
|
import type userPayload from '../../interfaces/user'
|
||||||
|
|
||||||
let user: userPayload
|
let user: userPayload
|
||||||
|
|
||||||
|
@ -21,13 +21,15 @@ describe('DELETE /post/delete', () => {
|
||||||
.send({
|
.send({
|
||||||
content: 'lorem ipsum'
|
content: 'lorem ipsum'
|
||||||
})
|
})
|
||||||
.set('Authorization', `Bearer ${user.token ?? ''}`).expect(200)
|
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||||
|
.expect(200)
|
||||||
|
|
||||||
await request(app)
|
await request(app)
|
||||||
.post('/post/delete')
|
.post('/post/delete')
|
||||||
.send({
|
.send({
|
||||||
postId: response.body.id
|
postId: response.body.id
|
||||||
})
|
})
|
||||||
.set('Authorization', `Bearer ${user.token ?? ''}`).expect(200)
|
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||||
|
.expect(200)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@ import app from '../../app'
|
||||||
import request from 'supertest'
|
import request from 'supertest'
|
||||||
import signUpNewUser from '../utils/create-user'
|
import signUpNewUser from '../utils/create-user'
|
||||||
import deleteUser from '../utils/delete-user'
|
import deleteUser from '../utils/delete-user'
|
||||||
import userPayload from '../../interfaces/user'
|
import type userPayload from '../../interfaces/user'
|
||||||
|
|
||||||
let postId: string
|
let postId: string
|
||||||
|
|
||||||
|
@ -14,9 +14,13 @@ describe('POST /post/info', () => {
|
||||||
|
|
||||||
const token = user.token ?? ''
|
const token = user.token ?? ''
|
||||||
|
|
||||||
const post = await request(app).post('/post/create').send({
|
const post = await request(app)
|
||||||
content: 'Hello world'
|
.post('/post/create')
|
||||||
}).set('Authorization', `Bearer ${token}`).expect(200)
|
.send({
|
||||||
|
content: 'Hello world'
|
||||||
|
})
|
||||||
|
.set('Authorization', `Bearer ${token}`)
|
||||||
|
.expect(200)
|
||||||
|
|
||||||
postId = post.body.id
|
postId = post.body.id
|
||||||
})
|
})
|
||||||
|
@ -26,15 +30,19 @@ describe('POST /post/info', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should respond with 200 status code and return some info about the post', async () => {
|
it('should respond with 200 status code and return some info about the post', async () => {
|
||||||
const response = await request(app).get(`/post/info?id=${postId}`).expect(200)
|
const response = await request(app)
|
||||||
|
.get(`/post/info?id=${postId}`)
|
||||||
|
.expect(200)
|
||||||
|
|
||||||
expect(response.body).toEqual(expect.objectContaining({
|
expect(response.body).toEqual(
|
||||||
id: expect.any(String),
|
expect.objectContaining({
|
||||||
content: expect.any(String),
|
id: expect.any(String),
|
||||||
createdAt: expect.any(String),
|
content: expect.any(String),
|
||||||
updatedAt: expect.any(String),
|
createdAt: expect.any(String),
|
||||||
author: expect.any(Object)
|
updatedAt: expect.any(String),
|
||||||
}))
|
author: expect.any(Object)
|
||||||
|
})
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should respond with 400 status code if the post does not exists', async () => {
|
it('should respond with 400 status code if the post does not exists', async () => {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import app from '../../app'
|
||||||
import request from 'supertest'
|
import request from 'supertest'
|
||||||
import signUpNewUser from '../utils/create-user'
|
import signUpNewUser from '../utils/create-user'
|
||||||
import deleteUser from '../utils/delete-user'
|
import deleteUser from '../utils/delete-user'
|
||||||
import userPayload from '../../interfaces/user'
|
import type userPayload from '../../interfaces/user'
|
||||||
|
|
||||||
let user: userPayload
|
let user: userPayload
|
||||||
|
|
||||||
|
@ -16,9 +16,13 @@ describe('PUT /post/update', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should create a new post and update the content of it', async () => {
|
it('should create a new post and update the content of it', async () => {
|
||||||
const post = await request(app).post('/post/create').send({
|
const post = await request(app)
|
||||||
content: 'Lorem'
|
.post('/post/create')
|
||||||
}).set('Authorization', `Bearer ${user.token ?? ''}`).expect(200)
|
.send({
|
||||||
|
content: 'Lorem'
|
||||||
|
})
|
||||||
|
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||||
|
.expect(200)
|
||||||
|
|
||||||
expect(post.body).toHaveProperty('id')
|
expect(post.body).toHaveProperty('id')
|
||||||
|
|
||||||
|
@ -30,19 +34,22 @@ describe('PUT /post/update', () => {
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.put('/post/update')
|
.put('/post/update')
|
||||||
.send(fieldsToUpdate)
|
.send(fieldsToUpdate)
|
||||||
.set('Authorization', `Bearer ${user.token ?? ''}`).expect(200)
|
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||||
|
.expect(200)
|
||||||
|
|
||||||
// Post content should be Lorem Ipsum
|
// Post content should be Lorem Ipsum
|
||||||
if (post.body.content === response.body.content) {
|
if (post.body.content === response.body.content) {
|
||||||
throw new Error('Post didn\'t update')
|
throw new Error("Post didn't update")
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(response.body).toEqual(expect.objectContaining({
|
expect(response.body).toEqual(
|
||||||
id: expect.any(String),
|
expect.objectContaining({
|
||||||
content: expect.any(String),
|
id: expect.any(String),
|
||||||
createdAt: expect.any(String),
|
content: expect.any(String),
|
||||||
updatedAt: expect.any(String),
|
createdAt: expect.any(String),
|
||||||
author: expect.any(Object)
|
updatedAt: expect.any(String),
|
||||||
}))
|
author: expect.any(Object)
|
||||||
|
})
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@ import request from 'supertest'
|
||||||
import app from '../../app'
|
import app from '../../app'
|
||||||
import deleteUser from '../utils/delete-user'
|
import deleteUser from '../utils/delete-user'
|
||||||
import signUpNewUser from '../utils/create-user'
|
import signUpNewUser from '../utils/create-user'
|
||||||
import userPayload from '../../interfaces/user'
|
import type userPayload from '../../interfaces/user'
|
||||||
|
|
||||||
let user: userPayload
|
let user: userPayload
|
||||||
|
|
||||||
|
@ -16,14 +16,20 @@ describe('POST /user/auth', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should respond with a error if the user does not exists', async () => {
|
it('should respond with a error if the user does not exists', async () => {
|
||||||
const response = await request(app).post('/user/auth').send({ email: 'mm@mm.com', password: 'aa' }).expect(400)
|
const response = await request(app)
|
||||||
|
.post('/user/auth')
|
||||||
|
.send({ email: 'mm@mm.com', password: 'aa' })
|
||||||
|
.expect(400)
|
||||||
|
|
||||||
expect(response.body).toHaveProperty('error')
|
expect(response.body).toHaveProperty('error')
|
||||||
expect(response.body.error).toBe('User does not exists')
|
expect(response.body.error).toBe('User does not exists')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should respond with a error if receive an invalid email or password', async () => {
|
it('should respond with a error if receive an invalid email or password', async () => {
|
||||||
const response = await request(app).post('/user/auth').send({ email: user.email, password: 'fake_pass' }).expect(400)
|
const response = await request(app)
|
||||||
|
.post('/user/auth')
|
||||||
|
.send({ email: user.email, password: 'fake_pass' })
|
||||||
|
.expect(400)
|
||||||
|
|
||||||
expect(response.body).toHaveProperty('error')
|
expect(response.body).toHaveProperty('error')
|
||||||
expect(response.body.error).toBe('Invalid email or password')
|
expect(response.body.error).toBe('Invalid email or password')
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import app from '../../app'
|
import app from '../../app'
|
||||||
import request from 'supertest'
|
import request from 'supertest'
|
||||||
import signUpNewUser from '../utils/create-user'
|
import signUpNewUser from '../utils/create-user'
|
||||||
import userPayload from '../../interfaces/user'
|
import type userPayload from '../../interfaces/user'
|
||||||
|
|
||||||
let user: userPayload
|
let user: userPayload
|
||||||
|
|
||||||
|
@ -11,7 +11,8 @@ describe('DELETE /user/delete', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should delete the user successfully', async () => {
|
it('should delete the user successfully', async () => {
|
||||||
await request(app).post('/user/delete')
|
await request(app)
|
||||||
|
.post('/user/delete')
|
||||||
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@ import app from '../../app'
|
||||||
import request from 'supertest'
|
import request from 'supertest'
|
||||||
import deleteUser from '../utils/delete-user'
|
import deleteUser from '../utils/delete-user'
|
||||||
import signUpNewUser from '../utils/create-user'
|
import signUpNewUser from '../utils/create-user'
|
||||||
import userPayload from '../../interfaces/user'
|
import type userPayload from '../../interfaces/user'
|
||||||
|
|
||||||
let user: userPayload
|
let user: userPayload
|
||||||
|
|
||||||
|
@ -16,7 +16,9 @@ describe('POST /user/info', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should respond with 200 status code and return the user data', async () => {
|
it('should respond with 200 status code and return the user data', async () => {
|
||||||
const response = await request(app).get(`/user/info?u=${user.username ?? ''}`).expect(200)
|
const response = await request(app)
|
||||||
|
.get(`/user/info?u=${user.username ?? ''}`)
|
||||||
|
.expect(200)
|
||||||
|
|
||||||
expect(response.body).toHaveProperty('profileImage')
|
expect(response.body).toHaveProperty('profileImage')
|
||||||
expect(response.body).toHaveProperty('displayName')
|
expect(response.body).toHaveProperty('displayName')
|
||||||
|
|
|
@ -2,7 +2,7 @@ import request from 'supertest'
|
||||||
import app from '../../app'
|
import app from '../../app'
|
||||||
import deleteUser from '../utils/delete-user'
|
import deleteUser from '../utils/delete-user'
|
||||||
import signUpNewUser from '../utils/create-user'
|
import signUpNewUser from '../utils/create-user'
|
||||||
import userPayload from '../../interfaces/user'
|
import type userPayload from '../../interfaces/user'
|
||||||
|
|
||||||
let user: userPayload
|
let user: userPayload
|
||||||
|
|
||||||
|
@ -17,19 +17,25 @@ describe('POST /user/signup', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should respond with a 400 status code if sent any invalid data', async () => {
|
it('should respond with a 400 status code if sent any invalid data', async () => {
|
||||||
await request(app).post('/user/signup').send({
|
await request(app)
|
||||||
username: 'username12@',
|
.post('/user/signup')
|
||||||
email: user.email,
|
.send({
|
||||||
password: user.password
|
username: 'username12@',
|
||||||
}).expect(400)
|
email: user.email,
|
||||||
|
password: user.password
|
||||||
|
})
|
||||||
|
.expect(400)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should respond with a 400 status code for an existing username or email', async () => {
|
it('should respond with a 400 status code for an existing username or email', async () => {
|
||||||
await request(app).post('/user/signup').send({
|
await request(app)
|
||||||
username: user.username,
|
.post('/user/signup')
|
||||||
email: user.email,
|
.send({
|
||||||
password: user.password
|
username: user.username,
|
||||||
}).expect(400)
|
email: user.email,
|
||||||
|
password: user.password
|
||||||
|
})
|
||||||
|
.expect(400)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should respond with a 400 status code if receive an empty body', async () => {
|
it('should respond with a 400 status code if receive an empty body', async () => {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import request from 'supertest'
|
||||||
import app from '../../app'
|
import app from '../../app'
|
||||||
import signUpNewUser from '../utils/create-user'
|
import signUpNewUser from '../utils/create-user'
|
||||||
import deleteUser from '../utils/delete-user'
|
import deleteUser from '../utils/delete-user'
|
||||||
import userPayload from '../../interfaces/user'
|
import type userPayload from '../../interfaces/user'
|
||||||
|
|
||||||
let user: userPayload
|
let user: userPayload
|
||||||
|
|
||||||
|
@ -23,12 +23,15 @@ describe('PUT /user/update', () => {
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.put('/user/update')
|
.put('/user/update')
|
||||||
.send(fieldsToUpdate)
|
.send(fieldsToUpdate)
|
||||||
.set('Authorization', `Bearer ${user.token ?? ''}`).expect(200)
|
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||||
|
.expect(200)
|
||||||
|
|
||||||
expect(response.body).toEqual(expect.objectContaining({
|
expect(response.body).toEqual(
|
||||||
displayName: expect.any(String),
|
expect.objectContaining({
|
||||||
username: expect.any(String),
|
displayName: expect.any(String),
|
||||||
createdAt: expect.any(String)
|
username: expect.any(String),
|
||||||
}))
|
createdAt: expect.any(String)
|
||||||
|
})
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import app from '../../app'
|
import app from '../../app'
|
||||||
import request from 'supertest'
|
import request from 'supertest'
|
||||||
import { faker } from '@faker-js/faker'
|
import { faker } from '@faker-js/faker'
|
||||||
import userPayload from '../../interfaces/user'
|
import type userPayload from '../../interfaces/user'
|
||||||
|
|
||||||
async function signUpNewUser (): Promise<userPayload> {
|
async function signUpNewUser (): Promise<userPayload> {
|
||||||
// To avoid conflicts with existing usernames or emails
|
// To avoid conflicts with existing usernames or emails
|
||||||
|
@ -9,18 +9,22 @@ async function signUpNewUser (): Promise<userPayload> {
|
||||||
const email = faker.internet.email()
|
const email = faker.internet.email()
|
||||||
const password = faker.internet.password() + '@1'
|
const password = faker.internet.password() + '@1'
|
||||||
|
|
||||||
await request(app).post('/user/signup').send({
|
await request(app)
|
||||||
username,
|
.post('/user/signup')
|
||||||
email,
|
.send({
|
||||||
password
|
username,
|
||||||
}).expect(200)
|
email,
|
||||||
|
password
|
||||||
|
})
|
||||||
|
.expect(200)
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.post('/user/auth')
|
.post('/user/auth')
|
||||||
.send({
|
.send({
|
||||||
email,
|
email,
|
||||||
password
|
password
|
||||||
}).expect(200)
|
})
|
||||||
|
.expect(200)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
username,
|
username,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from '../../clients/prisma-client'
|
||||||
|
|
||||||
export default async function deleteUser (username: string) {
|
export default async function deleteUser (username: string) {
|
||||||
|
|
126
tsconfig.json
126
tsconfig.json
|
@ -1,105 +1,47 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
/* Visit https://aka.ms/tsconfig to read more about this file */
|
|
||||||
/* Projects */
|
|
||||||
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
|
||||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
|
||||||
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
|
||||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
|
||||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
|
||||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
|
||||||
/* Language and Environment */
|
/* Language and Environment */
|
||||||
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
"target": "es2016",
|
||||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
|
||||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
|
||||||
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
|
||||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
|
||||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
|
||||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
|
||||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
|
||||||
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
|
||||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
|
||||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
|
||||||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
|
||||||
/* Modules */
|
/* Modules */
|
||||||
"module": "commonjs", /* Specify what module code is generated. */
|
"module": "commonjs",
|
||||||
"rootDir": "./", /* Specify the root folder within your source files. */
|
"rootDir": "./",
|
||||||
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
|
"baseUrl": "./src",
|
||||||
"baseUrl": "./src", /* Specify the base directory to resolve non-relative module names. */
|
"paths": {
|
||||||
/* Specify a set of entries that re-map imports to additional lookup locations. */
|
"clients/*": [
|
||||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
"clients/*"
|
||||||
|
],
|
||||||
|
"config/*": [
|
||||||
|
"config/*"
|
||||||
|
],
|
||||||
|
"controllers/*": [
|
||||||
|
"controllers/*"
|
||||||
|
],
|
||||||
|
"interfaces/*": [
|
||||||
|
"interfaces/*"
|
||||||
|
],
|
||||||
|
"lib/*": [
|
||||||
|
"lib/*"
|
||||||
|
],
|
||||||
|
"middlewares/*": [
|
||||||
|
"middlewares/*"
|
||||||
|
],
|
||||||
|
"services/*": [
|
||||||
|
"services/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
"src/@types/express.d.ts",
|
"src/@types/express.d.ts",
|
||||||
"src/@types/global.d.ts",
|
"src/@types/global.d.ts",
|
||||||
"node_modules/@types"
|
"node_modules/@types"
|
||||||
], /* Specify multiple folders that act like './node_modules/@types'. */
|
],
|
||||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
|
||||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
|
||||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
|
||||||
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
|
|
||||||
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
|
|
||||||
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
|
|
||||||
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
|
|
||||||
// "resolveJsonModule": true, /* Enable importing .json files. */
|
|
||||||
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
|
|
||||||
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
|
||||||
/* JavaScript Support */
|
|
||||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
|
||||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
|
||||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
|
||||||
/* Emit */
|
/* Emit */
|
||||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
"outDir": "./dist",
|
||||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
"removeComments": true,
|
||||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
|
||||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
|
||||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
|
||||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
|
||||||
"outDir": "./dist", /* Specify an output folder for all emitted files. */
|
|
||||||
"removeComments": true, /* Disable emitting comments. */
|
|
||||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
|
||||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
|
||||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
|
||||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
|
||||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
|
||||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
|
||||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
|
||||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
|
||||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
|
||||||
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
|
||||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
|
||||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
|
||||||
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
|
||||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
|
||||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
|
||||||
/* Interop Constraints */
|
/* Interop Constraints */
|
||||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
"esModuleInterop": true,
|
||||||
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
|
"forceConsistentCasingInFileNames": true,
|
||||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
|
||||||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
|
||||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
|
||||||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
|
||||||
/* Type Checking */
|
/* Type Checking */
|
||||||
"strict": true, /* Enable all strict type-checking options. */
|
"strict": true,
|
||||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
"skipLibCheck": true
|
||||||
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
|
||||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
|
||||||
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
|
||||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
|
||||||
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
|
||||||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
|
||||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
|
||||||
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
|
||||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
|
||||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
|
||||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
|
||||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
|
||||||
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
|
||||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
|
||||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
|
||||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
|
||||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
|
||||||
/* Completeness */
|
|
||||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
|
||||||
"skipLibCheck": true, /* Skip type checking all .d.ts files. */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue