mirror of
https://github.com/hknsh/project-knedita.git
synced 2024-11-28 17:41:15 +00:00
Changed TSC in favor of SWC. Added new tests, added new endpoints.
This commit is contained in:
parent
b21a832c13
commit
d07ccddb10
33 changed files with 379 additions and 72 deletions
1
.swcrc
1
.swcrc
|
@ -10,7 +10,6 @@
|
|||
"baseUrl": "./"
|
||||
},
|
||||
"exclude": [
|
||||
"tests/",
|
||||
"@types/",
|
||||
"interfaces/"
|
||||
],
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
A simple social media created with React Native and Express.
|
||||
|
||||
## To-do - Backend
|
||||
|
||||
- Create/update/delete Posts
|
||||
- Password recuperation
|
||||
- Two step verification
|
||||
|
@ -13,7 +14,8 @@ A simple social media created with React Native and Express.
|
|||
- Probably pinned posts
|
||||
- Authentication ✅
|
||||
- Add more verification (like, if the password is too short)
|
||||
- Set display name
|
||||
|
||||
## License
|
||||
|
||||
[MIT](https://choosealicense.com/licenses/mit/)
|
||||
|
||||
|
|
22
src/controllers/posts-router.ts
Normal file
22
src/controllers/posts-router.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* eslint-disable @typescript-eslint/no-misused-promises */
|
||||
|
||||
import { Router } from 'express'
|
||||
|
||||
// Controllers
|
||||
import postCreateController from './posts/post-create'
|
||||
import postDeleteController from './posts/post-delete'
|
||||
import postInfoController from './posts/post-info'
|
||||
import postUpdateController from './posts/post-update'
|
||||
|
||||
// Middlewares
|
||||
import ensureAuthenticated from '../middlewares/ensure-authenticated'
|
||||
|
||||
const postsRouter = Router()
|
||||
|
||||
// Posts related
|
||||
postsRouter.post('/create', ensureAuthenticated, postCreateController)
|
||||
postsRouter.post('/delete', ensureAuthenticated, postDeleteController)
|
||||
postsRouter.get('/info', postInfoController)
|
||||
postsRouter.put('/update', postUpdateController)
|
||||
|
||||
export default postsRouter
|
|
@ -1,11 +1,11 @@
|
|||
import createPostService from '../../services/post/create-post'
|
||||
import { posts } from '../../services/index'
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
async function createPostController (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 ?? ''
|
||||
|
||||
const result = await createPostService(content, id)
|
||||
const result = await posts.postCreate(content, id)
|
||||
|
||||
if (result instanceof Error) {
|
||||
res.status(400).json({
|
||||
|
@ -17,4 +17,4 @@ async function createPostController (req: Request, res: Response): Promise<void>
|
|||
res.json(result)
|
||||
}
|
||||
|
||||
export default createPostController
|
||||
export default postCreateController
|
20
src/controllers/posts/post-delete.ts
Normal file
20
src/controllers/posts/post-delete.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { posts } from '../../services/index'
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
async function postDeleteController (req: Request, res: Response): Promise<void> {
|
||||
const userId = req.user?.id ?? ''
|
||||
const postId = req.body.postId
|
||||
|
||||
const result = await posts.postDelete(postId, userId)
|
||||
|
||||
if (result instanceof Error) {
|
||||
res.status(400).json({
|
||||
error: result.message
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
}
|
||||
|
||||
export default postDeleteController
|
26
src/controllers/posts/post-info.ts
Normal file
26
src/controllers/posts/post-info.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { posts } from '../../services/index'
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
async function postInfoController (req: Request, res: Response): Promise<void> {
|
||||
const id = req.query.id as string
|
||||
|
||||
if (id === undefined) {
|
||||
res.status(400).json({
|
||||
error: 'Missing username'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const result = await posts.postInfo(id)
|
||||
|
||||
if (result instanceof Error) {
|
||||
res.status(400).json({
|
||||
error: result.message
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
}
|
||||
|
||||
export default postInfoController
|
17
src/controllers/posts/post-update.ts
Normal file
17
src/controllers/posts/post-update.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { posts } from '../../services/index'
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
async function postUpdateController (req: Request, res: Response): Promise<void> {
|
||||
const result = await posts.postUpdate()
|
||||
|
||||
if (result instanceof Error) {
|
||||
res.status(400).json({
|
||||
error: result.message
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
}
|
||||
|
||||
export default postUpdateController
|
24
src/controllers/users-router.ts
Normal file
24
src/controllers/users-router.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* eslint-disable @typescript-eslint/no-misused-promises */
|
||||
|
||||
import { Router } from 'express'
|
||||
|
||||
// Controllers
|
||||
import userAuthController from './users/user-auth'
|
||||
import userDeleteController from './users/user-delete'
|
||||
import userInfoController from './users/user-info'
|
||||
import userSignupController from './users/user-signup'
|
||||
import userUpdateController from './users/user-update'
|
||||
|
||||
// Middlewares
|
||||
import ensureAuthenticated from '../middlewares/ensure-authenticated'
|
||||
|
||||
const usersRouter = Router()
|
||||
|
||||
// Users related
|
||||
usersRouter.post('/auth', userAuthController)
|
||||
usersRouter.post('/delete', ensureAuthenticated, userDeleteController)
|
||||
usersRouter.get('/info', userInfoController)
|
||||
usersRouter.post('/signup', userSignupController)
|
||||
usersRouter.put('/update', ensureAuthenticated, userUpdateController)
|
||||
|
||||
export default usersRouter
|
|
@ -1,10 +1,10 @@
|
|||
import userAuthService from '../../services/user/user-auth'
|
||||
import { users } from '../../services/index'
|
||||
import type { Request, Response } from 'express'
|
||||
|
||||
async function userAuthController (req: Request, res: Response): Promise<void> {
|
||||
const { email, password } = req.body
|
||||
|
||||
const result = await userAuthService(email, password)
|
||||
const result = await users.userAuth(email, password)
|
||||
|
||||
if (result instanceof Error) {
|
||||
res.status(400).json({
|
18
src/controllers/users/user-delete.ts
Normal file
18
src/controllers/users/user-delete.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { users } from '../../services'
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
async function userDeleteController (req: Request, res: Response): Promise<void> {
|
||||
const userId = req.user?.id ?? ''
|
||||
const result = await users.userDelete(userId)
|
||||
|
||||
if (result instanceof Error) {
|
||||
res.status(400).json({
|
||||
error: result.message
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
}
|
||||
|
||||
export default userDeleteController
|
|
@ -1,10 +1,17 @@
|
|||
import userInfoService from '../../services/user/user-info'
|
||||
import { users } from '../../services'
|
||||
import type { Request, Response } from 'express'
|
||||
|
||||
async function userInfoController (req: Request, res: Response): Promise<void> {
|
||||
const id = req.user?.id ?? ''
|
||||
const username = req.query.u as string
|
||||
|
||||
const result = await userInfoService(id)
|
||||
if (username === undefined) {
|
||||
res.status(400).json({
|
||||
error: 'Missing username'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const result = await users.userInfo(username.toLowerCase())
|
||||
|
||||
if (result instanceof Error) {
|
||||
res.status(400).json({
|
|
@ -1,10 +1,10 @@
|
|||
import userSignupService from '../../services/user/user-signup'
|
||||
import { users } from '../../services'
|
||||
import type { Request, Response } from 'express'
|
||||
|
||||
async function userSignupController (req: Request, res: Response): Promise<void> {
|
||||
const { username, email, password } = req.body
|
||||
|
||||
const result = await userSignupService(username, email, password)
|
||||
const result = await users.userSignup(username, email, password)
|
||||
|
||||
if (result instanceof Error) {
|
||||
res.status(400).json({
|
17
src/controllers/users/user-update.ts
Normal file
17
src/controllers/users/user-update.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { users } from '../../services'
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
async function userUpdateController (req: Request, res: Response): Promise<void> {
|
||||
const result = await users.userUpdate()
|
||||
|
||||
if (result instanceof Error) {
|
||||
res.status(400).json({
|
||||
error: result.message
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
res.json(result)
|
||||
}
|
||||
|
||||
export default userUpdateController
|
|
@ -1,22 +1,12 @@
|
|||
import { Router } from 'express'
|
||||
|
||||
// Controllers
|
||||
import userSignupController from './controllers/user/user-signup'
|
||||
import userAuthController from './controllers/user/user-auth'
|
||||
import userInfoController from './controllers/user/user-info'
|
||||
import createPostController from './controllers/post/create-post'
|
||||
|
||||
// Middlewares
|
||||
import ensureAuthenticated from './middlewares/ensure-authenticated'
|
||||
// Routers
|
||||
import usersRouter from './controllers/users-router'
|
||||
import postsRouter from './controllers/posts-router'
|
||||
|
||||
const router = Router()
|
||||
|
||||
// User related
|
||||
router.post('/user/auth', userAuthController)
|
||||
router.post('/user/create', userSignupController)
|
||||
router.get('/user/info', ensureAuthenticated, userInfoController)
|
||||
|
||||
// Post related
|
||||
router.post('/post/create', ensureAuthenticated, createPostController)
|
||||
router.use('/user', usersRouter)
|
||||
router.use('/post', postsRouter)
|
||||
|
||||
export default router
|
||||
|
|
29
src/services/index.ts
Normal file
29
src/services/index.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import userAuthService from './users/user-auth'
|
||||
import userDeleteService from './users/user-delete'
|
||||
import userInfoService from './users/user-info'
|
||||
import userSignupService from './users/user-signup'
|
||||
import userUpdateService from './users/user-update'
|
||||
|
||||
import postCreateService from './posts/post-create'
|
||||
import postDeleteService from './posts/post-delete'
|
||||
import postInfoService from './posts/post-info'
|
||||
import postUpdateService from './posts/post-update'
|
||||
|
||||
// User services
|
||||
const users = {
|
||||
userAuth: userAuthService,
|
||||
userDelete: userDeleteService,
|
||||
userInfo: userInfoService,
|
||||
userSignup: userSignupService,
|
||||
userUpdate: userUpdateService
|
||||
}
|
||||
|
||||
// Post services
|
||||
const posts = {
|
||||
postCreate: postCreateService,
|
||||
postDelete: postDeleteService,
|
||||
postInfo: postInfoService,
|
||||
postUpdate: postUpdateService
|
||||
}
|
||||
|
||||
export { users, posts }
|
|
@ -1,6 +1,6 @@
|
|||
import prisma from '../../db'
|
||||
|
||||
async function createPostService (content: string, authorId: string): Promise<Object | Error> {
|
||||
async function postCreateService (content: string, authorId: string): Promise<Object | Error> {
|
||||
const user = await prisma.user.findFirst({ where: { id: authorId } })
|
||||
|
||||
if (user === null) {
|
||||
|
@ -17,4 +17,4 @@ async function createPostService (content: string, authorId: string): Promise<Ob
|
|||
return post
|
||||
}
|
||||
|
||||
export default createPostService
|
||||
export default postCreateService
|
29
src/services/posts/post-delete.ts
Normal file
29
src/services/posts/post-delete.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import prisma from '../../db'
|
||||
|
||||
async function postDeleteService (postId: string, userId: string): Promise<Object | Error> {
|
||||
const post = await prisma.post.findFirst({ where: { id: postId } })
|
||||
|
||||
console.log(postId, userId)
|
||||
|
||||
if (post === null) {
|
||||
return new Error('Post not found')
|
||||
}
|
||||
|
||||
if (await prisma.user.findFirst({ where: { id: userId } }) === null) {
|
||||
return new Error('User not found')
|
||||
}
|
||||
|
||||
if (post.authorId !== userId) {
|
||||
return new Error('Forbidden')
|
||||
}
|
||||
|
||||
await prisma.post.deleteMany({
|
||||
where: {
|
||||
id: postId
|
||||
}
|
||||
})
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
export default postDeleteService
|
29
src/services/posts/post-info.ts
Normal file
29
src/services/posts/post-info.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import prisma from '../../db'
|
||||
|
||||
async function postInfoService (id: string): Promise<Object | Error> {
|
||||
const post = await prisma.post.findFirst({
|
||||
where: {
|
||||
id
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
content: true,
|
||||
createdAt: true,
|
||||
updatedAt: true,
|
||||
author: {
|
||||
select: {
|
||||
displayName: true,
|
||||
username: true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (post === null) {
|
||||
return new Error('Post not found')
|
||||
}
|
||||
|
||||
return post
|
||||
}
|
||||
|
||||
export default postInfoService
|
6
src/services/posts/post-update.ts
Normal file
6
src/services/posts/post-update.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
import prisma from '../../db'
|
||||
|
||||
async function postUpdateService (): Promise<Object | Error> {
|
||||
return {}
|
||||
}
|
||||
export default postUpdateService
|
29
src/services/users/user-delete.ts
Normal file
29
src/services/users/user-delete.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import prisma from '../../db'
|
||||
|
||||
async function userDeleteService (userId: string): Promise<Object | Error> {
|
||||
const user = await prisma.user.findFirst({ where: { id: userId } })
|
||||
|
||||
if (user === null) {
|
||||
return new Error('User not found')
|
||||
}
|
||||
|
||||
if (user.id !== userId) {
|
||||
return new Error('Forbidden')
|
||||
}
|
||||
|
||||
await prisma.post.deleteMany({
|
||||
where: {
|
||||
authorId: user.id
|
||||
}
|
||||
})
|
||||
|
||||
await prisma.user.deleteMany({
|
||||
where: {
|
||||
id: userId
|
||||
}
|
||||
})
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
export default userDeleteService
|
|
@ -1,15 +1,22 @@
|
|||
import prisma from '../../db'
|
||||
|
||||
async function userInfoService (id: string): Promise<Object> {
|
||||
async function userInfoService (username: string): Promise<Object> {
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id
|
||||
username
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
displayName: true,
|
||||
username: true,
|
||||
createdAt: true
|
||||
createdAt: true,
|
||||
posts: {
|
||||
select: {
|
||||
id: true,
|
||||
content: true,
|
||||
createdAt: true,
|
||||
updatedAt: true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -28,7 +28,7 @@ async function userSignupService (username: string, email: string, password: str
|
|||
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
username,
|
||||
username: username.toLowerCase(),
|
||||
email,
|
||||
password: hashedPassword
|
||||
},
|
7
src/services/users/user-update.ts
Normal file
7
src/services/users/user-update.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import prisma from '../../db'
|
||||
|
||||
async function userUpdateService (): Promise<Object | Error> {
|
||||
return {}
|
||||
}
|
||||
|
||||
export default userUpdateService
|
|
@ -6,7 +6,7 @@ let token = ''
|
|||
|
||||
describe('POST /post/create', () => {
|
||||
beforeAll(async () => {
|
||||
await request(app).post('/user/create').send({
|
||||
await request(app).post('/user/signup').send({
|
||||
username: 'dummmyuser7',
|
||||
email: 'random1@email.com',
|
||||
password: 'pass'
|
9
src/tests/post/post-delete.spec.ts
Normal file
9
src/tests/post/post-delete.spec.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import prisma from '../../db'
|
||||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
|
||||
describe('DELETE /post/delete', () => {
|
||||
test('should ignore', () => {
|
||||
expect(1 + 1).toBe(2)
|
||||
})
|
||||
})
|
9
src/tests/post/post-info.spec.ts
Normal file
9
src/tests/post/post-info.spec.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import prisma from '../../db'
|
||||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
|
||||
describe('POST /post/info', () => {
|
||||
test('should ignore', () => {
|
||||
expect(1 + 1).toBe(2)
|
||||
})
|
||||
})
|
9
src/tests/post/post-update.spec.ts
Normal file
9
src/tests/post/post-update.spec.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import prisma from '../../db'
|
||||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
|
||||
describe('PUT /post/update', () => {
|
||||
test('should ignore', () => {
|
||||
expect(1 + 1).toBe(2)
|
||||
})
|
||||
})
|
9
src/tests/user/user-delete.spec.ts
Normal file
9
src/tests/user/user-delete.spec.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import prisma from '../../db'
|
||||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
|
||||
describe('DELETE /user/delete', () => {
|
||||
test('should ignore', () => {
|
||||
expect(1 + 1).toBe(2)
|
||||
})
|
||||
})
|
|
@ -2,24 +2,7 @@ import prisma from '../../db'
|
|||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
|
||||
let token = ''
|
||||
|
||||
describe('POST /user/info', () => {
|
||||
beforeAll(async () => {
|
||||
await request(app).post('/user/create').send({
|
||||
username: 'dummmyuser5',
|
||||
email: 'random3@email.com',
|
||||
password: 'pass'
|
||||
})
|
||||
|
||||
const response = await request(app).post('/user/auth').send({
|
||||
email: 'random3@email.com',
|
||||
password: 'pass'
|
||||
}).expect(200)
|
||||
|
||||
token = response.body.token
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await prisma.user.deleteMany({
|
||||
where: {
|
||||
|
@ -30,16 +13,24 @@ 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').set('Authorization', `Bearer ${token}`).expect(200)
|
||||
await prisma.user.create({
|
||||
data: {
|
||||
username: 'dummmyuser5',
|
||||
email: 'random3@email.com',
|
||||
password: 'pass'
|
||||
}
|
||||
})
|
||||
|
||||
const response = await request(app).get('/user/info?u=dummmyuser5').expect(200)
|
||||
|
||||
expect(response.body).toHaveProperty('id')
|
||||
expect(response.body).toHaveProperty('displayName')
|
||||
expect(response.body).toHaveProperty('username')
|
||||
expect(response.body).toHaveProperty('createdAt')
|
||||
expect(response.body).toHaveProperty('posts')
|
||||
})
|
||||
|
||||
it('should respond with 400 status code if the user send no token', async () => {
|
||||
const response = await request(app).get('/user/info').expect(401)
|
||||
it('should respond with 400 status code if the user send no username', async () => {
|
||||
const response = await request(app).get('/user/info?u=').expect(400)
|
||||
|
||||
expect(response.body).toHaveProperty('error')
|
||||
})
|
||||
|
|
|
@ -8,9 +8,9 @@ const mockUser = {
|
|||
password: 'totallysafepass'
|
||||
}
|
||||
|
||||
describe('POST /user/create', () => {
|
||||
describe('POST /user/signup', () => {
|
||||
it('should respond with a 200 status code', async () => {
|
||||
const response = await request(app).post('/user/create').send(mockUser).expect(200)
|
||||
const response = await request(app).post('/user/signup').send(mockUser).expect(200)
|
||||
|
||||
expect(response.body).toHaveProperty('displayName')
|
||||
expect(response.body).toHaveProperty('username')
|
||||
|
@ -18,7 +18,7 @@ describe('POST /user/create', () => {
|
|||
})
|
||||
|
||||
it('should respond with a 400 status code if sent any invalid data', async () => {
|
||||
await request(app).post('/user/create').send({
|
||||
await request(app).post('/user/signup').send({
|
||||
username: 'username12@',
|
||||
email: mockUser.email,
|
||||
password: mockUser.password
|
||||
|
@ -34,7 +34,7 @@ describe('POST /user/create', () => {
|
|||
}
|
||||
})
|
||||
|
||||
const response = await request(app).post('/user/create').send({
|
||||
const response = await request(app).post('/user/signup').send({
|
||||
username: 'dummmyuser2',
|
||||
email: 'user1@email.com',
|
||||
password: 'reallystrongpass'
|
||||
|
@ -52,7 +52,7 @@ describe('POST /user/create', () => {
|
|||
}
|
||||
})
|
||||
|
||||
const response = await request(app).post('/user/create').send({
|
||||
const response = await request(app).post('/user/signup').send({
|
||||
username: 'dummmyuser4',
|
||||
email: 'user13@email.com',
|
||||
password: '12345'
|
||||
|
@ -62,7 +62,7 @@ describe('POST /user/create', () => {
|
|||
})
|
||||
|
||||
it('should respond with a 400 status code if receive an empty body', async () => {
|
||||
const response = await request(app).post('/user/create').send({}).expect(400)
|
||||
const response = await request(app).post('/user/signup').send({}).expect(400)
|
||||
|
||||
expect(response.body).toHaveProperty('error')
|
||||
})
|
||||
|
|
9
src/tests/user/user-update.spec.ts
Normal file
9
src/tests/user/user-update.spec.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import prisma from '../../db'
|
||||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
|
||||
describe('PUT /user/update', () => {
|
||||
test('should ignore', () => {
|
||||
expect(1 + 1).toBe(2)
|
||||
})
|
||||
})
|
|
@ -26,14 +26,7 @@
|
|||
"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. */
|
||||
"paths": {
|
||||
"@services/*": [
|
||||
"services/*"
|
||||
],
|
||||
"@db/*": [
|
||||
"../prisma/*"
|
||||
]
|
||||
}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
/* 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. */
|
||||
"typeRoots": [
|
||||
"src/@types",
|
||||
|
|
Loading…
Reference in a new issue