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": {
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": false,
|
||||
"decorators": true,
|
||||
"dynamicImport": true
|
||||
},
|
||||
"target": "es2020",
|
||||
"baseUrl": "./"
|
||||
"jsc": {
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": false,
|
||||
"decorators": true,
|
||||
"dynamicImport": true
|
||||
},
|
||||
"exclude": [
|
||||
"@types/",
|
||||
"interfaces/"
|
||||
],
|
||||
"module": {
|
||||
"type": "commonjs"
|
||||
},
|
||||
"minify": true
|
||||
}
|
||||
"target": "es2020",
|
||||
"baseUrl": "./"
|
||||
},
|
||||
"exclude": ["@types/", "interfaces/"],
|
||||
"module": {
|
||||
"type": "commonjs"
|
||||
},
|
||||
"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
|
||||
|
||||
An open-source social media.
|
||||
|
@ -21,7 +20,6 @@ An open-source social media.
|
|||
- Image compression ✅
|
||||
- Following/unfollowing features ✅
|
||||
- Like posts ✅
|
||||
- Probably pinned posts
|
||||
- Authentication ✅
|
||||
- Add more verification (like, if the password is too short) ✅
|
||||
- Set display name ✅
|
||||
|
|
|
@ -11,7 +11,7 @@ services:
|
|||
- .env
|
||||
volumes:
|
||||
- postgres:/var/lib/postgresql/data
|
||||
|
||||
|
||||
redis:
|
||||
image: redis:alpine
|
||||
restart: unless-stopped
|
||||
|
@ -24,4 +24,4 @@ services:
|
|||
|
||||
volumes:
|
||||
postgres:
|
||||
name: backend-db
|
||||
name: backend-db
|
||||
|
|
|
@ -31,7 +31,7 @@ services:
|
|||
- .env
|
||||
volumes:
|
||||
- postgres:/var/lib/postgresql/data
|
||||
|
||||
|
||||
localstack:
|
||||
image: localstack/localstack
|
||||
container_name: localstack_main
|
||||
|
@ -45,7 +45,7 @@ services:
|
|||
- .env
|
||||
volumes:
|
||||
- localstack:/data
|
||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||
- '/var/run/docker.sock:/var/run/docker.sock'
|
||||
|
||||
redis:
|
||||
image: redis:alpine
|
||||
|
@ -62,4 +62,4 @@ volumes:
|
|||
name: backend-db
|
||||
redis:
|
||||
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",
|
||||
"scripts": {
|
||||
"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:build": "docker build -t api . && docker compose up -d",
|
||||
"docker:db": "docker compose -f docker-compose.db.yml up -d",
|
||||
"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:create": "prisma migrate dev --create-only",
|
||||
"migrate:reset": "prisma migrate reset",
|
||||
|
@ -43,16 +44,24 @@
|
|||
"@types/node": "^20.3.1",
|
||||
"@types/supertest": "^2.0.12",
|
||||
"@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",
|
||||
"nodemon": "^3.0.1",
|
||||
"pm2": "^4.2.3",
|
||||
"prettier": "^3.0.0",
|
||||
"prisma": "^5.0.0",
|
||||
"supertest": "^6.3.3",
|
||||
"ts-jest": "^29.1.0",
|
||||
"ts-node-dev": "^2.0.0",
|
||||
"ts-standard": "^12.0.2",
|
||||
"typescript": "^5.1.3"
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@prisma/client": "^5.0.0",
|
||||
|
|
|
@ -45,6 +45,8 @@ model PostLike {
|
|||
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 {
|
||||
id String @id @default(uuid())
|
||||
commentId String
|
||||
|
|
|
@ -4,6 +4,8 @@ const redisPassword = process.env.REDIS_PASSWORD ?? ''
|
|||
const redisHost = process.env.REDIS_HOST ?? ''
|
||||
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
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import multer from 'multer'
|
||||
import { Request } from 'express'
|
||||
import { type Request } from 'express'
|
||||
import path from 'path'
|
||||
import s3 from '../clients/s3-client'
|
||||
import s3 from 'clients/s3-client'
|
||||
import multerS3 from 'multer-s3'
|
||||
|
||||
const tempFolder = path.resolve(__dirname, '..', '..', 'temp', 'uploads')
|
||||
|
@ -18,7 +18,7 @@ const storageTypes = {
|
|||
const fileName: string = `${folder}/${req.user!.id}.webp`
|
||||
|
||||
callback(null, fileName)
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
s3: multerS3({
|
||||
|
@ -37,21 +37,22 @@ const storageTypes = {
|
|||
|
||||
const fileName: string = `${folder}/${req.user!.id}.jpg`
|
||||
callback(null, fileName)
|
||||
}
|
||||
})
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
const multerConfig = {
|
||||
dest: tempFolder,
|
||||
storage: storageTypes.s3,
|
||||
limits: {
|
||||
fileSize: 15 * 1024 * 1024 // 1mb
|
||||
fileSize: 15 * 1024 * 1024, // 1mb
|
||||
},
|
||||
fileFilter: (req: Request, file: Express.Multer.File, callback: multer.FileFilterCallback) => {
|
||||
const allowedMimes = [
|
||||
'image/jpeg',
|
||||
'image/png'
|
||||
]
|
||||
fileFilter: (
|
||||
req: Request,
|
||||
file: Express.Multer.File,
|
||||
callback: multer.FileFilterCallback,
|
||||
) => {
|
||||
const allowedMimes = ['image/jpeg', 'image/png']
|
||||
|
||||
if (allowedMimes.includes(file.mimetype)) {
|
||||
callback(null, true)
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
/* eslint-disable @typescript-eslint/no-misused-promises */
|
||||
import { Router } from 'express'
|
||||
|
||||
// Controllers
|
||||
import comments from './comments'
|
||||
|
||||
// Middlewares
|
||||
import authenticated from '../middlewares/authenticated'
|
||||
import authenticated from 'middlewares/authenticated'
|
||||
|
||||
const commentsRouter = Router()
|
||||
|
||||
|
|
|
@ -1,23 +1,26 @@
|
|||
import comment from '../../services/comments'
|
||||
import comment from 'services/comments'
|
||||
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 id = req.user?.id ?? ''
|
||||
|
||||
if (postId === undefined) {
|
||||
return badRequest(res, 'Expected post id')
|
||||
badRequest(res, 'Expected post id'); return
|
||||
}
|
||||
|
||||
if (content === undefined) {
|
||||
return badRequest(res, 'Expected comment content')
|
||||
badRequest(res, 'Expected comment content'); return
|
||||
}
|
||||
|
||||
const result = await comment.create(postId, content, id)
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
import comment from '../../services/comments'
|
||||
import comment from 'services/comments'
|
||||
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 id = req.user?.id ?? ''
|
||||
|
||||
if (commentId === undefined) {
|
||||
return badRequest(res, 'Expected comment id')
|
||||
badRequest(res, 'Expected comment id'); return
|
||||
}
|
||||
|
||||
const result = await comment.delete(commentId, id)
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
import comment from '../../services/comments'
|
||||
import comment from 'services/comments'
|
||||
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
|
||||
|
||||
if (commentId === undefined) {
|
||||
return badRequest(res, 'Expected comment id')
|
||||
badRequest(res, 'Expected comment id'); return
|
||||
}
|
||||
|
||||
const result = await comment.fetch(commentId)
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
import comment from '../../services/comments'
|
||||
import comment from 'services/comments'
|
||||
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
|
||||
|
||||
if (commentId === undefined) {
|
||||
return badRequest(res, 'Expected comment id')
|
||||
badRequest(res, 'Expected comment id'); return
|
||||
}
|
||||
|
||||
const result = await comment.fetchLikes(commentId)
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,23 +1,26 @@
|
|||
import comment from '../../services/comments'
|
||||
import comment from 'services/comments'
|
||||
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 id = req.user?.id ?? ''
|
||||
|
||||
if (commentId === undefined) {
|
||||
return badRequest(res, 'Expected comment content')
|
||||
badRequest(res, 'Expected comment content'); return
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
/* eslint-disable @typescript-eslint/no-misused-promises */
|
||||
import { Router } from 'express'
|
||||
|
||||
// Controllers
|
||||
import post from './posts'
|
||||
|
||||
// Middlewares
|
||||
import authenticated from '../middlewares/authenticated'
|
||||
import authenticated from 'middlewares/authenticated'
|
||||
|
||||
const postsRouter = Router()
|
||||
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
import post from '../../services/posts'
|
||||
import post from 'services/posts'
|
||||
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 id: string = req.user?.id ?? ''
|
||||
|
||||
if (content === undefined) {
|
||||
return badRequest(res, 'Expected post content')
|
||||
badRequest(res, 'Expected post content'); return
|
||||
}
|
||||
|
||||
const result = await post.create(content, id)
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
import post from '../../services/posts'
|
||||
import post from 'services/posts'
|
||||
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 postId = req.body.postId
|
||||
|
||||
const result = await post.delete(postId, userId)
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
import post from '../../services/posts'
|
||||
import post from 'services/posts'
|
||||
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
|
||||
|
||||
if (id === undefined) {
|
||||
return badRequest(res, 'Missing post id')
|
||||
badRequest(res, 'Missing post id'); return
|
||||
}
|
||||
|
||||
const result = await post.fetch(id)
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
import post from '../../services/posts'
|
||||
import post from 'services/posts'
|
||||
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
|
||||
|
||||
if (id === undefined) {
|
||||
return badRequest(res, 'Missing post id')
|
||||
badRequest(res, 'Missing post id'); return
|
||||
}
|
||||
|
||||
const result = await post.fetchLikes(id)
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
import post from '../../services/posts'
|
||||
import post from 'services/posts'
|
||||
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 userId = req.user?.id ?? ''
|
||||
|
||||
const result = await post.update(postId, content, userId)
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
/* eslint-disable @typescript-eslint/no-misused-promises */
|
||||
import { Router } from 'express'
|
||||
|
||||
// Controllers
|
||||
import user from './users'
|
||||
|
||||
// Middlewares
|
||||
import authenticated from '../middlewares/authenticated'
|
||||
import uploadFile from '../middlewares/upload-image'
|
||||
import authenticated from 'middlewares/authenticated'
|
||||
import uploadFile from 'middlewares/upload-image'
|
||||
|
||||
const usersRouter = Router()
|
||||
|
||||
|
@ -24,7 +23,12 @@ usersRouter.post('/like-post', authenticated, user.likePost)
|
|||
usersRouter.post('/signup', user.signup)
|
||||
|
||||
// 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)
|
||||
|
||||
export default usersRouter
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import user from '../../services/users'
|
||||
import user from 'services/users'
|
||||
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> {
|
||||
const { email, password } = req.body
|
||||
|
||||
const result = await user.auth(email, password)
|
||||
const result = await user.auth({ email, password })
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
import user from '../../services/users'
|
||||
import user from 'services/users'
|
||||
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 result = await user.delete(userId)
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
import user from '../../services/users'
|
||||
import user from 'services/users'
|
||||
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
|
||||
|
||||
if (username === undefined) {
|
||||
return badRequest(res, 'Missing username')
|
||||
badRequest(res, 'Missing username'); return
|
||||
}
|
||||
|
||||
const result = await user.fetchInfo(username.toLowerCase())
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import user from '../../services/users'
|
||||
import user from 'services/users'
|
||||
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
|
||||
|
||||
if (username === undefined) {
|
||||
return badRequest(res, 'Missing username')
|
||||
badRequest(res, 'Missing username'); return
|
||||
}
|
||||
|
||||
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 { 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 { userToFollow } = req.body
|
||||
|
||||
const result = await user.follow(userId, userToFollow)
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
import user from '../../services/users'
|
||||
import user from 'services/users'
|
||||
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 { 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) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
import user from '../../services/users'
|
||||
import user from 'services/users'
|
||||
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 { postId } = req.body
|
||||
|
||||
const result = await user.likePost(postId, userId)
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import user from '../../services/users'
|
||||
import { Request, Response } from 'express'
|
||||
import { badRequest } from '../../lib/http-errors'
|
||||
import user from 'services/users'
|
||||
import type { Request, Response } from 'express'
|
||||
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
|
||||
|
||||
if (username === undefined) {
|
||||
return badRequest(res, 'Missing username')
|
||||
badRequest(res, 'Missing username'); return
|
||||
}
|
||||
|
||||
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 { 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 result = await user.signup(username, email, password)
|
||||
const result = await user.signup({ username, email, password })
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
import user from '../../services/users'
|
||||
import user from 'services/users'
|
||||
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 id = req.user?.id ?? ''
|
||||
|
||||
const result = await user.update({ id, email, displayName, username })
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
import user from '../../services/users'
|
||||
import user from 'services/users'
|
||||
import type { Request, Response } from 'express'
|
||||
import { badRequest } from '../../lib/http-errors'
|
||||
import { badRequest } from 'lib/http-errors'
|
||||
|
||||
let url
|
||||
|
||||
async function userUploadPictureController (req: Request, res: Response): Promise<void> {
|
||||
async function userUploadPictureController (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
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 ?? ''
|
||||
|
@ -23,7 +26,7 @@ async function userUploadPictureController (req: Request, res: Response): Promis
|
|||
const result = await user.uploadPicture(userId, url)
|
||||
|
||||
if (result instanceof Error) {
|
||||
return badRequest(res, result.message)
|
||||
badRequest(res, result.message); return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
|
|
|
@ -2,8 +2,8 @@ interface userPayload {
|
|||
id?: string
|
||||
displayName?: string | null
|
||||
username?: string
|
||||
password?: string
|
||||
email?: string
|
||||
password?: string
|
||||
token?: string
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,26 @@
|
|||
import sharp from 'sharp'
|
||||
import s3 from '../clients/s3-client'
|
||||
import s3 from 'clients/s3-client'
|
||||
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
|
||||
const { Body } = await s3.send(new GetObjectCommand({
|
||||
Bucket: process.env.AWS_BUCKET ?? '',
|
||||
Key: imageName
|
||||
}))
|
||||
const { Body } = await s3.send(
|
||||
new GetObjectCommand({
|
||||
Bucket: process.env.AWS_BUCKET ?? '',
|
||||
Key: imageName
|
||||
})
|
||||
)
|
||||
|
||||
const imageBuffer = await Body?.transformToByteArray()
|
||||
|
||||
const compressedImageBuffer = await sharp(imageBuffer)
|
||||
.resize(
|
||||
isProfilePicture === 'true' ? 200 : undefined,
|
||||
isProfilePicture === 'true' ? 200 : undefined
|
||||
)
|
||||
.jpeg({ quality: 65 })
|
||||
.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 })
|
||||
}
|
||||
|
||||
|
@ -16,6 +20,9 @@ export const forbidden = (res: Response, message = 'Forbidden'): void => {
|
|||
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)
|
||||
}
|
||||
|
|
|
@ -1,29 +1,38 @@
|
|||
import { verify } from 'jsonwebtoken'
|
||||
import prisma from '../clients/prisma-client'
|
||||
import prisma from 'clients/prisma-client'
|
||||
import type { Response, Request, NextFunction } from 'express'
|
||||
import jwtPayload from '../interfaces/jwt'
|
||||
import { unauthorized } from '../lib/http-errors'
|
||||
import type jwtPayload from 'interfaces/jwt'
|
||||
import { unauthorized } from 'lib/http-errors'
|
||||
|
||||
async function authenticated (req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if (req.headers.authorization === undefined || req.headers.authorization.length === 0) {
|
||||
return unauthorized(res, 'Missing token')
|
||||
async function authenticated (
|
||||
req: Request,
|
||||
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]
|
||||
|
||||
try {
|
||||
const decoded = await new Promise<jwtPayload | undefined>((resolve, reject) => {
|
||||
verify(token, process.env.JWT_ACCESS_SECRET ?? '', (error, decoded) => {
|
||||
if (error != null) {
|
||||
reject(error)
|
||||
} else {
|
||||
resolve(decoded as jwtPayload)
|
||||
}
|
||||
})
|
||||
})
|
||||
const decoded = await new Promise<jwtPayload | undefined>(
|
||||
(resolve, reject) => {
|
||||
verify(token, process.env.JWT_ACCESS_SECRET ?? '', (error, decoded) => {
|
||||
if (error != null) {
|
||||
reject(error)
|
||||
} else {
|
||||
resolve(decoded as jwtPayload)
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
if (decoded == null) {
|
||||
return unauthorized(res, 'Invalid token')
|
||||
unauthorized(res, 'Invalid token'); return
|
||||
}
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
|
@ -33,12 +42,12 @@ async function authenticated (req: Request, res: Response, next: NextFunction):
|
|||
})
|
||||
|
||||
if (user == null) {
|
||||
return unauthorized(res, 'User does not exists')
|
||||
unauthorized(res, 'User does not exists'); return
|
||||
}
|
||||
|
||||
req.user = decoded
|
||||
|
||||
return next()
|
||||
next()
|
||||
} catch (error) {
|
||||
unauthorized(res, `JWT Error: ${(error as Error).message}`)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import rateLimit from 'express-rate-limit'
|
||||
import RedisStore from 'rate-limit-redis'
|
||||
import redis from '../clients/redis-client'
|
||||
import redis from 'clients/redis-client'
|
||||
|
||||
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 multer from 'multer'
|
||||
import multerConfig from '../config/multer'
|
||||
import compressImage from '../lib/compress-image'
|
||||
import { badRequest } from '../lib/http-errors'
|
||||
import multerConfig from 'config/multer'
|
||||
import compressImage from 'lib/compress-image'
|
||||
import { badRequest } from 'lib/http-errors'
|
||||
|
||||
function uploadImage (req: Request, res: Response, next: NextFunction) {
|
||||
const upload = multer(multerConfig).single('image')
|
||||
|
||||
upload(req, res, async (cb: multer.MulterError | Error | any) => {
|
||||
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) {
|
||||
return badRequest(res, cb.message)
|
||||
badRequest(res, cb.message); return
|
||||
}
|
||||
|
||||
if (req.file === undefined) {
|
||||
return badRequest(res, 'Expected file')
|
||||
badRequest(res, 'Expected file'); return
|
||||
}
|
||||
|
||||
// @ts-expect-error property `key` does not exists in types
|
||||
await compressImage(req.file?.key)
|
||||
await compressImage(req.file?.key, req.body.isProfilePicture)
|
||||
|
||||
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({
|
||||
where: {
|
||||
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({
|
||||
where: {
|
||||
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({
|
||||
where: {
|
||||
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({
|
||||
where: {
|
||||
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({
|
||||
where: {
|
||||
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 } })
|
||||
|
||||
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({
|
||||
|
|
|
@ -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 } })
|
||||
|
||||
if (post === null) {
|
||||
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')
|
||||
}
|
||||
|
||||
|
|
|
@ -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({
|
||||
where: {
|
||||
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({
|
||||
where: {
|
||||
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 } })
|
||||
|
||||
if (post === null) {
|
||||
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')
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import * as bcrypt from 'bcrypt'
|
||||
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({
|
||||
where: {
|
||||
email
|
||||
|
@ -17,7 +21,10 @@ async function userAuthService (email: string, password: string): Promise<Object
|
|||
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) {
|
||||
return new Error('Invalid email or password')
|
||||
|
@ -25,7 +32,11 @@ async function userAuthService (email: string, password: string): Promise<Object
|
|||
|
||||
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 {
|
||||
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 } })
|
||||
|
||||
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({
|
||||
where: {
|
||||
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({
|
||||
where: {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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({
|
||||
where: {
|
||||
username: {
|
||||
|
|
|
@ -1,17 +1,24 @@
|
|||
import * as bcrypt from 'bcrypt'
|
||||
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 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) {
|
||||
return new Error('Missing fields')
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -19,7 +26,9 @@ async function userSignupService (username: string, email: string, password: str
|
|||
}
|
||||
|
||||
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)) {
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
import userPayload from '../../interfaces/user'
|
||||
import prisma from '../../clients/prisma-client'
|
||||
import type userPayload from 'interfaces/user'
|
||||
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 } })
|
||||
|
||||
if (user === null) {
|
||||
|
@ -13,14 +18,14 @@ async function userUpdateService ({ id, email, displayName, username }: userPayl
|
|||
|
||||
if (email !== undefined && email.trim() !== user.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')
|
||||
}
|
||||
}
|
||||
|
||||
if (username !== undefined && username.trim() !== user.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')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 } })
|
||||
|
||||
if (user == null) {
|
||||
|
|
|
@ -2,7 +2,7 @@ import app from '../../app'
|
|||
import request from 'supertest'
|
||||
import signUpNewUser from '../utils/create-user'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import userPayload from '../../interfaces/user'
|
||||
import type userPayload from '../../interfaces/user'
|
||||
|
||||
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 () => {
|
||||
const response = await request(app).post('/post/create').send({
|
||||
content: 'Hello world'
|
||||
}).set('Authorization', `Bearer ${user.token ?? ''}`).expect(200)
|
||||
const response = await request(app)
|
||||
.post('/post/create')
|
||||
.send({
|
||||
content: 'Hello world'
|
||||
})
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||
.expect(200)
|
||||
|
||||
expect(response.body).toEqual(expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
content: expect.any(String),
|
||||
authorId: expect.any(String),
|
||||
createdAt: expect.any(String),
|
||||
updatedAt: expect.any(String)
|
||||
}))
|
||||
expect(response.body).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
content: expect.any(String),
|
||||
authorId: 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 () => {
|
||||
|
|
|
@ -2,7 +2,7 @@ import app from '../../app'
|
|||
import request from 'supertest'
|
||||
import signUpNewUser from '../utils/create-user'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import userPayload from '../../interfaces/user'
|
||||
import type userPayload from '../../interfaces/user'
|
||||
|
||||
let user: userPayload
|
||||
|
||||
|
@ -21,13 +21,15 @@ describe('DELETE /post/delete', () => {
|
|||
.send({
|
||||
content: 'lorem ipsum'
|
||||
})
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`).expect(200)
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||
.expect(200)
|
||||
|
||||
await request(app)
|
||||
.post('/post/delete')
|
||||
.send({
|
||||
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 signUpNewUser from '../utils/create-user'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import userPayload from '../../interfaces/user'
|
||||
import type userPayload from '../../interfaces/user'
|
||||
|
||||
let postId: string
|
||||
|
||||
|
@ -14,9 +14,13 @@ describe('POST /post/info', () => {
|
|||
|
||||
const token = user.token ?? ''
|
||||
|
||||
const post = await request(app).post('/post/create').send({
|
||||
content: 'Hello world'
|
||||
}).set('Authorization', `Bearer ${token}`).expect(200)
|
||||
const post = await request(app)
|
||||
.post('/post/create')
|
||||
.send({
|
||||
content: 'Hello world'
|
||||
})
|
||||
.set('Authorization', `Bearer ${token}`)
|
||||
.expect(200)
|
||||
|
||||
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 () => {
|
||||
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({
|
||||
id: expect.any(String),
|
||||
content: expect.any(String),
|
||||
createdAt: expect.any(String),
|
||||
updatedAt: expect.any(String),
|
||||
author: expect.any(Object)
|
||||
}))
|
||||
expect(response.body).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
content: expect.any(String),
|
||||
createdAt: expect.any(String),
|
||||
updatedAt: expect.any(String),
|
||||
author: expect.any(Object)
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
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 signUpNewUser from '../utils/create-user'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import userPayload from '../../interfaces/user'
|
||||
import type userPayload from '../../interfaces/user'
|
||||
|
||||
let user: userPayload
|
||||
|
||||
|
@ -16,9 +16,13 @@ describe('PUT /post/update', () => {
|
|||
})
|
||||
|
||||
it('should create a new post and update the content of it', async () => {
|
||||
const post = await request(app).post('/post/create').send({
|
||||
content: 'Lorem'
|
||||
}).set('Authorization', `Bearer ${user.token ?? ''}`).expect(200)
|
||||
const post = await request(app)
|
||||
.post('/post/create')
|
||||
.send({
|
||||
content: 'Lorem'
|
||||
})
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||
.expect(200)
|
||||
|
||||
expect(post.body).toHaveProperty('id')
|
||||
|
||||
|
@ -30,19 +34,22 @@ describe('PUT /post/update', () => {
|
|||
const response = await request(app)
|
||||
.put('/post/update')
|
||||
.send(fieldsToUpdate)
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`).expect(200)
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||
.expect(200)
|
||||
|
||||
// Post content should be Lorem Ipsum
|
||||
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({
|
||||
id: expect.any(String),
|
||||
content: expect.any(String),
|
||||
createdAt: expect.any(String),
|
||||
updatedAt: expect.any(String),
|
||||
author: expect.any(Object)
|
||||
}))
|
||||
expect(response.body).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
content: expect.any(String),
|
||||
createdAt: expect.any(String),
|
||||
updatedAt: expect.any(String),
|
||||
author: expect.any(Object)
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -2,7 +2,7 @@ import request from 'supertest'
|
|||
import app from '../../app'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import signUpNewUser from '../utils/create-user'
|
||||
import userPayload from '../../interfaces/user'
|
||||
import type userPayload from '../../interfaces/user'
|
||||
|
||||
let user: userPayload
|
||||
|
||||
|
@ -16,14 +16,20 @@ describe('POST /user/auth', () => {
|
|||
})
|
||||
|
||||
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.error).toBe('User does not exists')
|
||||
})
|
||||
|
||||
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.error).toBe('Invalid email or password')
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
import signUpNewUser from '../utils/create-user'
|
||||
import userPayload from '../../interfaces/user'
|
||||
import type userPayload from '../../interfaces/user'
|
||||
|
||||
let user: userPayload
|
||||
|
||||
|
@ -11,7 +11,8 @@ describe('DELETE /user/delete', () => {
|
|||
})
|
||||
|
||||
it('should delete the user successfully', async () => {
|
||||
await request(app).post('/user/delete')
|
||||
await request(app)
|
||||
.post('/user/delete')
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||
.expect(200)
|
||||
})
|
||||
|
|
|
@ -2,7 +2,7 @@ import app from '../../app'
|
|||
import request from 'supertest'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import signUpNewUser from '../utils/create-user'
|
||||
import userPayload from '../../interfaces/user'
|
||||
import type userPayload from '../../interfaces/user'
|
||||
|
||||
let user: userPayload
|
||||
|
||||
|
@ -16,7 +16,9 @@ describe('POST /user/info', () => {
|
|||
})
|
||||
|
||||
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('displayName')
|
||||
|
|
|
@ -2,7 +2,7 @@ import request from 'supertest'
|
|||
import app from '../../app'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import signUpNewUser from '../utils/create-user'
|
||||
import userPayload from '../../interfaces/user'
|
||||
import type userPayload from '../../interfaces/user'
|
||||
|
||||
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 () => {
|
||||
await request(app).post('/user/signup').send({
|
||||
username: 'username12@',
|
||||
email: user.email,
|
||||
password: user.password
|
||||
}).expect(400)
|
||||
await request(app)
|
||||
.post('/user/signup')
|
||||
.send({
|
||||
username: 'username12@',
|
||||
email: user.email,
|
||||
password: user.password
|
||||
})
|
||||
.expect(400)
|
||||
})
|
||||
|
||||
it('should respond with a 400 status code for an existing username or email', async () => {
|
||||
await request(app).post('/user/signup').send({
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
password: user.password
|
||||
}).expect(400)
|
||||
await request(app)
|
||||
.post('/user/signup')
|
||||
.send({
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
password: user.password
|
||||
})
|
||||
.expect(400)
|
||||
})
|
||||
|
||||
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 signUpNewUser from '../utils/create-user'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import userPayload from '../../interfaces/user'
|
||||
import type userPayload from '../../interfaces/user'
|
||||
|
||||
let user: userPayload
|
||||
|
||||
|
@ -23,12 +23,15 @@ describe('PUT /user/update', () => {
|
|||
const response = await request(app)
|
||||
.put('/user/update')
|
||||
.send(fieldsToUpdate)
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`).expect(200)
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||
.expect(200)
|
||||
|
||||
expect(response.body).toEqual(expect.objectContaining({
|
||||
displayName: expect.any(String),
|
||||
username: expect.any(String),
|
||||
createdAt: expect.any(String)
|
||||
}))
|
||||
expect(response.body).toEqual(
|
||||
expect.objectContaining({
|
||||
displayName: expect.any(String),
|
||||
username: expect.any(String),
|
||||
createdAt: expect.any(String)
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
import { faker } from '@faker-js/faker'
|
||||
import userPayload from '../../interfaces/user'
|
||||
import type userPayload from '../../interfaces/user'
|
||||
|
||||
async function signUpNewUser (): Promise<userPayload> {
|
||||
// To avoid conflicts with existing usernames or emails
|
||||
|
@ -9,18 +9,22 @@ async function signUpNewUser (): Promise<userPayload> {
|
|||
const email = faker.internet.email()
|
||||
const password = faker.internet.password() + '@1'
|
||||
|
||||
await request(app).post('/user/signup').send({
|
||||
username,
|
||||
email,
|
||||
password
|
||||
}).expect(200)
|
||||
await request(app)
|
||||
.post('/user/signup')
|
||||
.send({
|
||||
username,
|
||||
email,
|
||||
password
|
||||
})
|
||||
.expect(200)
|
||||
|
||||
const response = await request(app)
|
||||
.post('/user/auth')
|
||||
.send({
|
||||
email,
|
||||
password
|
||||
}).expect(200)
|
||||
})
|
||||
.expect(200)
|
||||
|
||||
return {
|
||||
username,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
||||
import prisma from '../../clients/prisma-client'
|
||||
|
||||
export default async function deleteUser (username: string) {
|
||||
|
|
126
tsconfig.json
126
tsconfig.json
|
@ -1,105 +1,47 @@
|
|||
{
|
||||
"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 */
|
||||
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
// "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. */
|
||||
"target": "es2016",
|
||||
/* Modules */
|
||||
"module": "commonjs", /* Specify what module code is generated. */
|
||||
"rootDir": "./", /* Specify the root folder within your source files. */
|
||||
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
"baseUrl": "./src", /* Specify the base directory to resolve non-relative module names. */
|
||||
/* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
"module": "commonjs",
|
||||
"rootDir": "./",
|
||||
"baseUrl": "./src",
|
||||
"paths": {
|
||||
"clients/*": [
|
||||
"clients/*"
|
||||
],
|
||||
"config/*": [
|
||||
"config/*"
|
||||
],
|
||||
"controllers/*": [
|
||||
"controllers/*"
|
||||
],
|
||||
"interfaces/*": [
|
||||
"interfaces/*"
|
||||
],
|
||||
"lib/*": [
|
||||
"lib/*"
|
||||
],
|
||||
"middlewares/*": [
|
||||
"middlewares/*"
|
||||
],
|
||||
"services/*": [
|
||||
"services/*"
|
||||
]
|
||||
},
|
||||
"typeRoots": [
|
||||
"src/@types/express.d.ts",
|
||||
"src/@types/global.d.ts",
|
||||
"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 */
|
||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "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. */
|
||||
"outDir": "./dist",
|
||||
"removeComments": true,
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "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. */
|
||||
// "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. */
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
/* Type Checking */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||
// "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. */
|
||||
"strict": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue