#
tokens: 12192/50000 46/46 files
lines: on (toggle) GitHub
raw markdown copy reset
# Directory Structure

```
├── .gitignore
├── jest.config.ts
├── package.json
├── prisma
│   ├── migrations
│   │   ├── 20220819211355_create_deliveryman
│   │   │   └── migration.sql
│   │   ├── 20220819213758_update_name_deliveryman
│   │   │   └── migration.sql
│   │   ├── 20220819213956_create_clients_table
│   │   │   └── migration.sql
│   │   ├── 20220819214400_create_deliveries_table
│   │   │   └── migration.sql
│   │   ├── 20220819233031_alter_table_deliveries
│   │   │   └── migration.sql
│   │   ├── 20220819233224_alter_endat_deliveries_table
│   │   │   └── migration.sql
│   │   ├── 20220819234017_alter_end_date
│   │   │   └── migration.sql
│   │   └── migration_lock.toml
│   └── schema.prisma
├── src
│   ├── @types
│   │   └── express
│   │       └── index.d.ts
│   ├── database
│   │   ├── prismaClient.ts
│   │   └── repositories
│   │       ├── ClientRepository.ts
│   │       └── interfaces
│   │           └── IClientRepository.ts
│   ├── kafka
│   │   └── producer.ts
│   ├── middlewares
│   │   ├── ensureAuthClient.ts
│   │   └── ensureAuthDeliveryman.ts
│   ├── modules
│   │   ├── account
│   │   │   ├── authenticateClient
│   │   │   │   ├── AuthenticateClientController.ts
│   │   │   │   └── AuthenticateClientUseCase.ts
│   │   │   └── authenticateDeliveryman
│   │   │       ├── AuthenticateDeliverymanController.ts
│   │   │       └── AuthenticateDeliverymanUseCase.ts
│   │   ├── clients
│   │   │   └── useCases
│   │   │       ├── createClient
│   │   │       │   ├── createClient.spec.ts
│   │   │       │   ├── createClientController.ts
│   │   │       │   ├── createClienteUseCase.ts
│   │   │       │   └── index.ts
│   │   │       └── findClientDeliveries
│   │   │           ├── FindClientDeliveries.spec.ts
│   │   │           ├── FindClientDeliveriesController.ts
│   │   │           ├── FindClientDeliveriesUseCase.ts
│   │   │           └── index.ts
│   │   ├── deliveries
│   │   │   ├── updateEndDate
│   │   │   │   ├── UpdateEndDateController.ts
│   │   │   │   └── UpdateEndDateUseCase.ts
│   │   │   └── useCases
│   │   │       ├── createDelivery
│   │   │       │   ├── CreateDeliveryController.ts
│   │   │       │   └── CreateDeliveryUseCase.ts
│   │   │       ├── findAllAvailable
│   │   │       │   ├── FindAllAvailableController.ts
│   │   │       │   └── FindAllAvailableUseCase.ts
│   │   │       └── updateDeliveryman
│   │   │           ├── UpdateDeliverymanController.ts
│   │   │           └── UpdateDeliverymanUseCase.ts
│   │   └── deliveryman
│   │       └── useCases
│   │           ├── createDeliveryman
│   │           │   ├── CreateDeliverymanController.ts
│   │           │   └── CreateDeliverymanUseCase.ts
│   │           └── findAllDeliveries
│   │               ├── FindAllDeliveriesController.ts
│   │               └── FindAllDeliveriesUseCase.ts
│   ├── routes.ts
│   ├── server.ts
│   └── tests
│       └── inMemoryDatabases
│           └── InMemoryClientsRepository.ts
├── tsconfig.json
└── yarn.lock
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
1 | node_modules
2 | # Keep environment variables out of version control
3 | .env
4 | 
```

--------------------------------------------------------------------------------
/prisma/migrations/20220819234017_alter_end_date/migration.sql:
--------------------------------------------------------------------------------

```sql
1 | -- AlterTable
2 | ALTER TABLE "deliveries" ALTER COLUMN "end_at" DROP DEFAULT;
3 | 
```

--------------------------------------------------------------------------------
/prisma/migrations/20220819233224_alter_endat_deliveries_table/migration.sql:
--------------------------------------------------------------------------------

```sql
1 | -- AlterTable
2 | ALTER TABLE "deliveries" ALTER COLUMN "end_at" SET DEFAULT CURRENT_TIMESTAMP;
3 | 
```

--------------------------------------------------------------------------------
/src/database/prismaClient.ts:
--------------------------------------------------------------------------------

```typescript
1 | import { PrismaClient } from "@prisma/client";
2 | 
3 | const prisma = new PrismaClient()
4 | 
5 | export { prisma }
```

--------------------------------------------------------------------------------
/src/@types/express/index.d.ts:
--------------------------------------------------------------------------------

```typescript
1 | declare namespace Express{
2 |   export interface Request{
3 |     id_client: string;
4 |     id_deliveryman: string;
5 |   }
6 | }
```

--------------------------------------------------------------------------------
/prisma/migrations/migration_lock.toml:
--------------------------------------------------------------------------------

```toml
1 | # Please do not edit this file manually
2 | # It should be added in your version-control system (i.e. Git)
3 | provider = "postgresql"
```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
1 | {
2 |   "compilerOptions": {
3 |     "sourceMap": true,
4 |     "outDir": "dist",
5 |     "strict": true,
6 |     "lib": ["esnext"],
7 |     "esModuleInterop": true
8 |   }
9 | }
```

--------------------------------------------------------------------------------
/prisma/migrations/20220819213956_create_clients_table/migration.sql:
--------------------------------------------------------------------------------

```sql
 1 | -- CreateTable
 2 | CREATE TABLE "clients" (
 3 |     "id" TEXT NOT NULL,
 4 |     "username" TEXT NOT NULL,
 5 |     "password" TEXT NOT NULL,
 6 | 
 7 |     CONSTRAINT "clients_pkey" PRIMARY KEY ("id")
 8 | );
 9 | 
10 | -- CreateIndex
11 | CREATE UNIQUE INDEX "clients_username_key" ON "clients"("username");
12 | 
```

--------------------------------------------------------------------------------
/prisma/migrations/20220819211355_create_deliveryman/migration.sql:
--------------------------------------------------------------------------------

```sql
 1 | -- CreateTable
 2 | CREATE TABLE "Deliveryman" (
 3 |     "id" TEXT NOT NULL,
 4 |     "username" TEXT NOT NULL,
 5 |     "password" TEXT NOT NULL,
 6 | 
 7 |     CONSTRAINT "Deliveryman_pkey" PRIMARY KEY ("id")
 8 | );
 9 | 
10 | -- CreateIndex
11 | CREATE UNIQUE INDEX "Deliveryman_username_key" ON "Deliveryman"("username");
12 | 
```

--------------------------------------------------------------------------------
/src/modules/deliveries/useCases/findAllAvailable/FindAllAvailableUseCase.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { prisma } from "../../../../database/prismaClient";
 2 | 
 3 | export class FindAllAvailableUseCase{
 4 |   async execute(){
 5 |     const deliveries = await prisma.deliveries.findMany({
 6 |       where: {
 7 |         end_at: null,
 8 |         id_deliveryman: null,
 9 |       }
10 |     })
11 | 
12 |     return deliveries
13 |   }
14 | }
```

--------------------------------------------------------------------------------
/src/database/repositories/interfaces/IClientRepository.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Clients } from "@prisma/client";
 2 | 
 3 | export interface CreateRequestProps{
 4 |   username: string;
 5 |   password: string
 6 | }
 7 | 
 8 | export interface FindRequestProps{
 9 |   id_client: string;
10 | }
11 | 
12 | export interface IClientRepository {
13 |   create({ username, password }: CreateRequestProps): Promise<Clients>
14 |   find({ id_client }: FindRequestProps): Promise<Clients[]>
15 | }
```

--------------------------------------------------------------------------------
/src/modules/deliveries/useCases/createDelivery/CreateDeliveryUseCase.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { prisma } from "../../../../database/prismaClient";
 2 | 
 3 | interface ICreateDelivery{
 4 |   item_name: string;
 5 |   id_client: string;
 6 | }
 7 | 
 8 | export class CreateDeliveryUseCase{
 9 |   async execute({ item_name, id_client }: ICreateDelivery){
10 | 
11 |     const delivery = await prisma.deliveries.create({
12 |       data: {
13 |         item_name,
14 |         id_client,
15 |       }
16 |     })
17 | 
18 |     return delivery
19 |   }
20 | }
```

--------------------------------------------------------------------------------
/src/modules/deliveries/updateEndDate/UpdateEndDateUseCase.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { prisma } from "../../../database/prismaClient";
 2 | 
 3 | interface IUpdateEndDate{
 4 |   id_delivery: string;
 5 | }
 6 | 
 7 | export class UpdateEndDateUseCase{
 8 |   async execute({ id_delivery }: IUpdateEndDate){
 9 |     const delivery = await prisma.deliveries.update({
10 |       where: {
11 |         id: id_delivery,
12 |       },
13 |       data: {
14 |         end_at: new Date()
15 |       }
16 |     })
17 | 
18 |     return delivery
19 |   }
20 | }
```

--------------------------------------------------------------------------------
/src/modules/deliveries/useCases/findAllAvailable/FindAllAvailableController.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Request, Response } from "express";
 2 | import { FindAllAvailableUseCase } from "./findAllAvailableUseCase";
 3 | 
 4 | 
 5 | 
 6 | export class FindAllAvailableController{
 7 |   async handle(request: Request, response: Response){
 8 |     const findAllAvailableUseCase = new FindAllAvailableUseCase()
 9 | 
10 |     const deliveries = await findAllAvailableUseCase.execute()
11 | 
12 |     return response.json(deliveries)
13 |   }
14 | }
```

--------------------------------------------------------------------------------
/prisma/migrations/20220819233031_alter_table_deliveries/migration.sql:
--------------------------------------------------------------------------------

```sql
 1 | -- DropForeignKey
 2 | ALTER TABLE "deliveries" DROP CONSTRAINT "deliveries_id_deliveryman_fkey";
 3 | 
 4 | -- AlterTable
 5 | ALTER TABLE "deliveries" ALTER COLUMN "id_deliveryman" DROP NOT NULL,
 6 | ALTER COLUMN "end_at" DROP NOT NULL;
 7 | 
 8 | -- AddForeignKey
 9 | ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_id_deliveryman_fkey" FOREIGN KEY ("id_deliveryman") REFERENCES "deliveryman"("id") ON DELETE SET NULL ON UPDATE CASCADE;
10 | 
```

--------------------------------------------------------------------------------
/src/modules/deliveries/updateEndDate/UpdateEndDateController.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Request, Response } from "express";
 2 | import { UpdateEndDateUseCase } from "./UpdateEndDateUseCase";
 3 | 
 4 | 
 5 | 
 6 | export class UpdateEndDateController{
 7 |   async handle(request: Request, response: Response){
 8 |     const { id } = request.params;
 9 | 
10 |     const updateEndDateUseCase = new UpdateEndDateUseCase()
11 | 
12 |     const result = await updateEndDateUseCase.execute({
13 |       id_delivery: id
14 |     })
15 | 
16 |     return response.json(result)
17 |   }
18 | }
```

--------------------------------------------------------------------------------
/src/modules/deliveries/useCases/updateDeliveryman/UpdateDeliverymanUseCase.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { prisma } from "../../../../database/prismaClient";
 2 | 
 3 | interface IUpdateDeliveryman{
 4 |   id_delivery: string;
 5 |   id_deliveryman: string;
 6 | }
 7 | 
 8 | export class UpdateDeliverymanUseCase{
 9 |   async execute({ id_delivery, id_deliveryman }: IUpdateDeliveryman){
10 |     const result = await prisma.deliveries.update({
11 |       where: {
12 |         id: id_delivery
13 |       },
14 | 
15 |       data: {
16 |         id_deliveryman
17 |       }
18 |     })
19 | 
20 |     return result
21 |   }
22 | }
```

--------------------------------------------------------------------------------
/src/modules/deliveryman/useCases/findAllDeliveries/FindAllDeliveriesController.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Request, Response } from "express";
 2 | import { FindAllDeliveriesUseCase } from "./FindAllDeliveriesUseCase";
 3 | 
 4 | 
 5 | 
 6 | export class FindAllDeliveriesController{
 7 |   async handle(request: Request, response: Response){
 8 |     const { id_deliveryman } = request
 9 | 
10 |     const findAllDeliveriesUseCase = new FindAllDeliveriesUseCase()
11 | 
12 |     const result = await findAllDeliveriesUseCase.execute({
13 |       id_deliveryman,
14 |     })
15 | 
16 |     return response.json(result)
17 |   }
18 | }
```

--------------------------------------------------------------------------------
/src/modules/clients/useCases/createClient/createClientController.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Request, Response } from "express";
 2 | import { CreateClientUseCase } from "./createClienteUseCase";
 3 | 
 4 | export class CreateClientController{
 5 |   constructor (private createClientUseCase: CreateClientUseCase){}
 6 | 
 7 |   async handle(request: Request, response: Response){
 8 |     const { username, password } = request.body;
 9 | 
10 |     const result = await this.createClientUseCase.execute({
11 |       username,
12 |       password
13 |     })
14 | 
15 |     return response.json(result)
16 |   }
17 | }
```

--------------------------------------------------------------------------------
/prisma/migrations/20220819213758_update_name_deliveryman/migration.sql:
--------------------------------------------------------------------------------

```sql
 1 | /*
 2 |   Warnings:
 3 | 
 4 |   - You are about to drop the `Deliveryman` table. If the table is not empty, all the data it contains will be lost.
 5 | 
 6 | */
 7 | -- DropTable
 8 | DROP TABLE "Deliveryman";
 9 | 
10 | -- CreateTable
11 | CREATE TABLE "deliveryman" (
12 |     "id" TEXT NOT NULL,
13 |     "username" TEXT NOT NULL,
14 |     "password" TEXT NOT NULL,
15 | 
16 |     CONSTRAINT "deliveryman_pkey" PRIMARY KEY ("id")
17 | );
18 | 
19 | -- CreateIndex
20 | CREATE UNIQUE INDEX "deliveryman_username_key" ON "deliveryman"("username");
21 | 
```

--------------------------------------------------------------------------------
/src/modules/clients/useCases/findClientDeliveries/FindClientDeliveriesUseCase.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { prisma } from "../../../../database/prismaClient";
 2 | import { IClientRepository } from "../../../../database/repositories/interfaces/IClientRepository";
 3 | 
 4 | interface IFindClientDeliveries{
 5 |   id_client: string;
 6 | }
 7 | 
 8 | export class FindClientDeliveriesUseCase{
 9 |   constructor(
10 |     private clientRepository: IClientRepository
11 |   ){}
12 | 
13 |   async execute({id_client}: IFindClientDeliveries){
14 |     const client = await this.clientRepository.find({id_client})
15 | 
16 |     return client
17 |   }
18 | }
```

--------------------------------------------------------------------------------
/src/modules/account/authenticateClient/AuthenticateClientController.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Request, Response } from "express";
 2 | import { AuthenticateClientUseCase } from "./AuthenticateClientUseCase";
 3 | 
 4 | 
 5 | 
 6 | export class AuthenticateClientController{
 7 |   async handle(request: Request, response: Response){
 8 |     const { username, password } = request.body;
 9 | 
10 |     const authenticateClientUseCase = new AuthenticateClientUseCase()
11 |     const result = await authenticateClientUseCase.execute({
12 |       username,
13 |       password
14 |     })
15 | 
16 |     return response.json(result)
17 |   }
18 | }
```

--------------------------------------------------------------------------------
/src/modules/clients/useCases/findClientDeliveries/FindClientDeliveriesController.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Request, Response } from "express";
 2 | import { FindClientDeliveriesUseCase } from "./FindClientDeliveriesUseCase";
 3 | 
 4 | 
 5 | 
 6 | export class FindClientDeliveriesController{
 7 |   constructor(
 8 |     private findClientDeliveriesUseCase: FindClientDeliveriesUseCase
 9 |   ){}
10 | 
11 |   async handle(request: Request, response: Response){
12 |     const { id_client } = request
13 | 
14 |     const result = await this.findClientDeliveriesUseCase.execute({
15 |       id_client
16 |     })
17 | 
18 |     return response.json(result)
19 |   }
20 | }
```

--------------------------------------------------------------------------------
/src/modules/deliveries/useCases/createDelivery/CreateDeliveryController.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Request, Response } from "express";
 2 | import { CreateDeliveryUseCase } from "./CreateDeliveryUseCase";
 3 | 
 4 | export class CreateDeliveryController{
 5 |   async handle(request: Request, response: Response){
 6 |     const { item_name } = request.body;
 7 |     const { id_client } = request 
 8 | 
 9 |     const createDeliveryUseCase = new CreateDeliveryUseCase()
10 | 
11 |     const delivery = await createDeliveryUseCase.execute({
12 |       id_client,
13 |       item_name
14 |     })
15 | 
16 |     return response.json(delivery)
17 |   }
18 | }
```

--------------------------------------------------------------------------------
/src/modules/clients/useCases/createClient/index.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { ClientRepository } from "../../../../database/repositories/ClientRepository";
 2 | import { CreateClientController } from "./createClientController";
 3 | import { CreateClientUseCase } from "./createClienteUseCase";
 4 | 
 5 | const clientRepository = ClientRepository.getInstance()
 6 | 
 7 | const createClientUseCase = new CreateClientUseCase(clientRepository)
 8 | 
 9 | const createClientController = new CreateClientController(createClientUseCase)
10 | 
11 | export { createClientController, clientRepository, createClientUseCase }
12 | 
```

--------------------------------------------------------------------------------
/src/modules/account/authenticateDeliveryman/AuthenticateDeliverymanController.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Request, Response } from "express";
 2 | import { AuthenticateDeliverymanUseCase } from "./AuthenticateDeliverymanUseCase";
 3 | 
 4 | 
 5 | 
 6 | export class AuthenticateDeliverymanController{
 7 |   async handle(request: Request, response: Response){
 8 |     const { username, password } = request.body;
 9 | 
10 |     const authenticateDeliverymanUseCase = new AuthenticateDeliverymanUseCase()
11 |     const result = await authenticateDeliverymanUseCase.execute({
12 |       username,
13 |       password
14 |     })
15 | 
16 |     return response.json(result)
17 |   }
18 | }
```

--------------------------------------------------------------------------------
/src/modules/deliveries/useCases/updateDeliveryman/UpdateDeliverymanController.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Request, Response } from "express";
 2 | import { UpdateDeliverymanUseCase } from "./UpdateDeliverymanUseCase";
 3 | 
 4 | export class UpdateDeliverymanController{
 5 |   async handle(request: Request, response: Response){
 6 |     const { id } = request.params
 7 |     const { id_deliveryman } = request
 8 | 
 9 |     const updateDeliverymanUseCase = new UpdateDeliverymanUseCase()
10 | 
11 |     const delivery = await updateDeliverymanUseCase.execute({
12 |       id_delivery: id,
13 |       id_deliveryman
14 |     })
15 | 
16 |     return response.json(delivery)
17 |   }
18 | }
```

--------------------------------------------------------------------------------
/src/modules/deliveryman/useCases/findAllDeliveries/FindAllDeliveriesUseCase.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { prisma } from "../../../../database/prismaClient";
 2 | 
 3 | interface IFindAllDeliveries{
 4 |   id_deliveryman: string;
 5 | }
 6 | 
 7 | export class FindAllDeliveriesUseCase{
 8 |   async execute({ id_deliveryman }: IFindAllDeliveries){
 9 |     const deliveryman = await prisma.deliveryman.findFirst({
10 |       where: {
11 |         id: id_deliveryman,
12 |       },
13 | 
14 |       select: {
15 |         id: true,
16 |         username: true,
17 |         Deliveries: {
18 |           where: {
19 |             end_at: null
20 |           }
21 |         }
22 |       }
23 |     })
24 | 
25 |     return deliveryman
26 |   }
27 | }
```

--------------------------------------------------------------------------------
/src/modules/clients/useCases/findClientDeliveries/index.ts:
--------------------------------------------------------------------------------

```typescript
1 | import { ClientRepository } from "../../../../database/repositories/ClientRepository";
2 | import { FindClientDeliveriesController } from "./FindClientDeliveriesController";
3 | import { FindClientDeliveriesUseCase } from "./FindClientDeliveriesUseCase";
4 | 
5 | const clientRepository = ClientRepository.getInstance()
6 | const findClientDeliveriesUseCase = new FindClientDeliveriesUseCase(clientRepository)
7 | const findClientDeliveriesController = new FindClientDeliveriesController(findClientDeliveriesUseCase)
8 | 
9 | export { findClientDeliveriesController }
```

--------------------------------------------------------------------------------
/src/server.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import express, { NextFunction, Request, Response } from "express";
 2 | import "express-async-errors"
 3 | import { routes } from "./routes";
 4 | 
 5 | const app = express()
 6 | 
 7 | app.use(express.json())
 8 | 
 9 | app.use(routes);
10 | 
11 | app.use((err: Error, request: Request, response: Response, next: NextFunction) => {
12 |   if(err instanceof Error){
13 |     return response.status(400).json({
14 |       message: err.message
15 |     })
16 |   }
17 | 
18 |   return response.status(500).json({
19 |     status: "error",
20 |     message: "internal server error"
21 |   })
22 | })
23 | 
24 | app.listen(3333, () => console.log('server is running'))
25 | 
```

--------------------------------------------------------------------------------
/src/middlewares/ensureAuthClient.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { NextFunction, Request, Response } from "express";
 2 | import { verify } from "jsonwebtoken";
 3 | 
 4 | interface IPayload{
 5 |   sub: string;
 6 | }
 7 | 
 8 | export async function ensureAuthClient(request: Request, response: Response, next: NextFunction){
 9 |   const authHeader = request.headers.authorization;
10 | 
11 |   if(!authHeader){
12 |     return response.status(401).json({
13 |       message: "token missing"
14 |     })
15 |   }
16 | 
17 |   const [, token] = authHeader.split(" ");
18 | 
19 |   try{
20 |     const { sub } = verify(token, 'a905d89574379cec8ba1fc0438bf9597') as IPayload;
21 |     
22 |     request.id_client = sub;
23 | 
24 |     return next()
25 |   }catch{
26 |     return response.status(401).json({
27 |       message: "Invalid token"
28 |     })
29 |   }
30 |   
31 | }
```

--------------------------------------------------------------------------------
/src/middlewares/ensureAuthDeliveryman.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { NextFunction, Request, Response } from "express";
 2 | import { verify } from "jsonwebtoken";
 3 | 
 4 | interface IPayload{
 5 |   sub: string;
 6 | }
 7 | 
 8 | export async function ensureAuthDeliveryman(request: Request, response: Response, next: NextFunction){
 9 |   const authHeader = request.headers.authorization;
10 | 
11 |   if(!authHeader){
12 |     return response.status(401).json({
13 |       message: "token missing"
14 |     })
15 |   }
16 | 
17 |   const [, token] = authHeader.split(" ");
18 | 
19 |   try{
20 |     const { sub } = verify(token, 'a905d89574379cec8ba1fc0438bf9597') as IPayload;
21 |     
22 |     request.id_deliveryman = sub;
23 | 
24 |     return next()
25 |   }catch{
26 |     return response.status(401).json({
27 |       message: "Invalid token"
28 |     })
29 |   }
30 |   
31 | }
```

--------------------------------------------------------------------------------
/prisma/migrations/20220819214400_create_deliveries_table/migration.sql:
--------------------------------------------------------------------------------

```sql
 1 | -- CreateTable
 2 | CREATE TABLE "deliveries" (
 3 |     "id" TEXT NOT NULL,
 4 |     "id_client" TEXT NOT NULL,
 5 |     "id_deliveryman" TEXT NOT NULL,
 6 |     "item_name" TEXT NOT NULL,
 7 |     "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
 8 |     "end_at" TIMESTAMP(3) NOT NULL,
 9 | 
10 |     CONSTRAINT "deliveries_pkey" PRIMARY KEY ("id")
11 | );
12 | 
13 | -- AddForeignKey
14 | ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_id_client_fkey" FOREIGN KEY ("id_client") REFERENCES "clients"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
15 | 
16 | -- AddForeignKey
17 | ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_id_deliveryman_fkey" FOREIGN KEY ("id_deliveryman") REFERENCES "deliveryman"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
18 | 
```

--------------------------------------------------------------------------------
/src/modules/deliveryman/useCases/createDeliveryman/CreateDeliverymanController.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Request, Response } from "express";
 2 | import { producer } from "../../../../kafka/producer";
 3 | import { CreateDeliverymanUseCase } from "./CreateDeliverymanUseCase";
 4 | import { randomUUID } from 'node:crypto'
 5 | 
 6 | 
 7 | export class CreateDeliverymanController {
 8 |   async handle(request: Request, response: Response){
 9 |     const { username, password } = request.body;
10 | 
11 |     const createDeliverymanUseCase = new CreateDeliverymanUseCase()
12 |     const result = await createDeliverymanUseCase.execute({
13 |       username,
14 |       password
15 |     })
16 | 
17 |     await producer({
18 |       category: 'deliveryman',
19 |       content: `Novo deliveryman criado: ${username}`,
20 |       recipientId: randomUUID()
21 |     })
22 | 
23 |     return response.json(result)
24 |   }
25 | }
```

--------------------------------------------------------------------------------
/src/modules/clients/useCases/createClient/createClienteUseCase.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { prisma } from "../../../../database/prismaClient";
 2 | import { IClientRepository } from "../../../../database/repositories/interfaces/IClientRepository";
 3 | 
 4 | interface ICreateClient{
 5 |   username: string;
 6 |   password: string;
 7 | }
 8 | 
 9 | export class CreateClientUseCase{
10 |   constructor(private clientRepository: IClientRepository){}
11 |   async execute({ username, password }: ICreateClient){
12 |     const clientAlreadyExists = await prisma.clients.findFirst({
13 |       where: {
14 |         username: {
15 |           equals: username,
16 |           mode: "insensitive"
17 |         }
18 |       }
19 |     })
20 | 
21 |     if(clientAlreadyExists){
22 |       throw new Error("Client already exists")
23 |     }
24 | 
25 |     const client = this.clientRepository.create({password, username})
26 | 
27 |     return client
28 |   }
29 | }
```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "backend-entregas",
 3 |   "version": "1.0.0",
 4 |   "main": "index.js",
 5 |   "license": "MIT",
 6 |   "type": "commonjs",
 7 |   "scripts": {
 8 |     "dev": "ts-node-dev --exit-child --transpile-only --ignore-watch node_modules src/server.ts",
 9 |     "test": "jest"
10 |   },
11 |   "devDependencies": {
12 |     "@types/bcrypt": "^5.0.0",
13 |     "@types/express": "^4.17.13",
14 |     "@types/jest": "^29.4.0",
15 |     "@types/jsonwebtoken": "^8.5.8",
16 |     "jest": "^29.4.1",
17 |     "prisma": "^4.2.1",
18 |     "ts-jest": "^29.0.5",
19 |     "ts-node-dev": "^2.0.0",
20 |     "typescript": "^4.7.4"
21 |   },
22 |   "dependencies": {
23 |     "@prisma/client": "^4.2.1",
24 |     "bcrypt": "^5.0.1",
25 |     "express": "^4.18.1",
26 |     "express-async-errors": "^3.1.1",
27 |     "jsonwebtoken": "^8.5.1",
28 |     "kafkajs": "^2.2.3"
29 |   }
30 | }
31 | 
```

--------------------------------------------------------------------------------
/src/modules/clients/useCases/findClientDeliveries/FindClientDeliveries.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { InMemoryClientRepository } from "../../../../tests/inMemoryDatabases/InMemoryClientsRepository"
 2 | import { FindClientDeliveriesUseCase } from "./FindClientDeliveriesUseCase"
 3 | 
 4 | const clientRepository = new InMemoryClientRepository()
 5 | const findClientDeliveries = new FindClientDeliveriesUseCase(clientRepository)
 6 | 
 7 | describe("Find client Delivires", () => {
 8 |   it("should found a client delivery", async() => {
 9 |     const client = await findClientDeliveries.execute({
10 |       id_client: '455667'
11 |     })
12 | 
13 |     expect(client).toHaveLength(1)
14 |   })
15 | 
16 |   it("should return an error if client not found", async() => {
17 |     expect(async () => {
18 |       await findClientDeliveries.execute({
19 |         id_client: '645456654'
20 |       })
21 |     }).rejects.toThrow()
22 |   })
23 | })
```

--------------------------------------------------------------------------------
/src/modules/account/authenticateClient/AuthenticateClientUseCase.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { prisma } from "../../../database/prismaClient";
 2 | import { compare } from "bcrypt"
 3 | import { sign } from "jsonwebtoken"
 4 | 
 5 | interface IAuthenticateClient {
 6 |   username: string;
 7 |   password: string
 8 | }
 9 | 
10 | export class AuthenticateClientUseCase{
11 |   async execute({ username, password }: IAuthenticateClient){
12 |     const client = await prisma.clients.findFirst({
13 |       where: {
14 |         username
15 |       }
16 |     })
17 | 
18 |     if(!client){
19 |       throw new Error("Username or password is invalid!")
20 |     }
21 | 
22 |     const passwordMatch = await compare(password, client.password)
23 | 
24 |     if(!passwordMatch){
25 |       throw new Error("Username or password is invalid!")
26 |     }
27 | 
28 |     const token = sign( {username}, "a905d89574379cec8ba1fc0438bf9597", {
29 |       subject: client.id,
30 |       expiresIn: "1d"
31 |     })
32 | 
33 |     return token
34 |   }
35 | }
```

--------------------------------------------------------------------------------
/src/modules/deliveryman/useCases/createDeliveryman/CreateDeliverymanUseCase.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { hash } from "bcrypt";
 2 | import { prisma } from "../../../../database/prismaClient";
 3 | 
 4 | interface ICreateDeliveryman{
 5 |   username: string;
 6 |   password: string;
 7 | }
 8 | 
 9 | export class CreateDeliverymanUseCase{
10 |   async execute({ username, password }: ICreateDeliveryman){
11 |     // validar se username já existe
12 |     const deliverymanAlreadyExists = await prisma.deliveryman.findFirst({
13 |       where: {
14 |         username: {
15 |           equals: username,
16 |           mode: "insensitive"
17 |         }
18 |       }
19 |     })
20 | 
21 |     if(deliverymanAlreadyExists){
22 |       throw new Error("Deliveryman already exists!")
23 |     }
24 | 
25 |     const hashPassword = await hash(password, 10);
26 | 
27 |     const deliveryman = await prisma.deliveryman.create({
28 |       data: {
29 |         username,
30 |         password: hashPassword
31 |       }
32 |     })
33 | 
34 |     return deliveryman
35 | 
36 |   }
37 | }
```

--------------------------------------------------------------------------------
/src/modules/account/authenticateDeliveryman/AuthenticateDeliverymanUseCase.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { prisma } from "../../../database/prismaClient";
 2 | import { compare } from "bcrypt"
 3 | import { sign } from "jsonwebtoken"
 4 | 
 5 | interface IAuthenticateDeliveryman {
 6 |   username: string;
 7 |   password: string
 8 | }
 9 | 
10 | export class AuthenticateDeliverymanUseCase{
11 |   async execute({ username, password }: IAuthenticateDeliveryman){
12 |     const deliveryman = await prisma.deliveryman.findFirst({
13 |       where: {
14 |         username
15 |       }
16 |     })
17 | 
18 |     if(!deliveryman){
19 |       throw new Error("Username or password is invalid!")
20 |     }
21 | 
22 |     const passwordMatch = await compare(password, deliveryman.password)
23 | 
24 |     if(!passwordMatch){
25 |       throw new Error("Username or password is invalid!")
26 |     }
27 | 
28 |     const token = sign( {username}, "a905d89574379cec8ba1fc0438bf9597", {
29 |       subject: deliveryman.id,
30 |       expiresIn: "1d"
31 |     })
32 | 
33 |     return token
34 |   }
35 | }
```

--------------------------------------------------------------------------------
/src/kafka/producer.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import {Kafka} from 'kafkajs'
 2 | 
 3 | interface MessagesProps{
 4 |   content: string;
 5 |   category: string;
 6 |   recipientId: string;
 7 | }
 8 | 
 9 | export async function producer({category, content, recipientId}: MessagesProps){
10 |   const kafka = new Kafka({
11 |     clientId: 'entregas-node',
12 |     brokers: ['stable-spider-6900-us1-kafka.upstash.io:9092'],
13 |     sasl: {
14 |       mechanism: 'scram-sha-256',
15 |       username: 'c3RhYmxlLXNwaWRlci02OTAwJJw1OKOjqd2WIqt7-XXtHqrcZPbhL1aLjGLyXXM',
16 |       password: 'b55b6a4a24404e199df02c2f6bc5b806',
17 |     },
18 |     ssl: true,
19 |   })
20 | 
21 |   const producer = kafka.producer()
22 | 
23 |   await producer.connect()
24 |   await producer.send({
25 |     topic: 'notifications.send-notification',
26 |     messages: [
27 |       {
28 |         value: JSON.stringify({
29 |           content,
30 |           category,
31 |           recipientId
32 |         })
33 |       }
34 |     ]
35 |   })
36 | 
37 |   await producer.disconnect()
38 | }
```

--------------------------------------------------------------------------------
/src/modules/clients/useCases/createClient/createClient.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { InMemoryClientRepository } from "../../../../tests/inMemoryDatabases/InMemoryClientsRepository"
 2 | import { CreateClientUseCase } from "./createClienteUseCase"
 3 | 
 4 | const clientRepository = new InMemoryClientRepository()
 5 | const createClientUseCase = new CreateClientUseCase(clientRepository)
 6 | 
 7 | describe('create client tests', () => {
 8 |   it('should create a client', async () => {
 9 |     const client = await createClientUseCase.execute({
10 |       password: String(Math.random()),
11 |       username: "Jhon Doe " + `${String(Math.random())}`,
12 |     })
13 | 
14 |     expect(client).toHaveProperty('id')
15 |   })
16 | 
17 |   it('should return an error if username already exists', async () => {
18 |     expect(async () => {
19 |       await createClientUseCase.execute({
20 |         password: String(Math.random()),
21 |         username: "jhon doe"
22 |       })
23 | 
24 |       await createClientUseCase.execute({
25 |         password: String(Math.random()),
26 |         username: "jhon doe"
27 |       })
28 |     }).rejects.toThrow("Client already exists");
29 |   })
30 | })
```

--------------------------------------------------------------------------------
/src/tests/inMemoryDatabases/InMemoryClientsRepository.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Clients } from "@prisma/client";
 2 | import { CreateRequestProps, FindRequestProps, IClientRepository } from "../../database/repositories/interfaces/IClientRepository";
 3 | import { randomUUID } from 'node:crypto'
 4 | 
 5 | export class InMemoryClientRepository implements IClientRepository{
 6 |   clients: Clients[]
 7 | 
 8 |   constructor(){
 9 |     this.clients = [{
10 |       username: 'Jhon Doe',
11 |       password: '123',
12 |       id: '455667'
13 |     }]
14 |   }
15 | 
16 |   async create({ username, password }: CreateRequestProps): Promise<Clients> {
17 |     const clientAlreadyExists = this.clients.find((client) => client.username === username)
18 | 
19 |     if(clientAlreadyExists){
20 |       throw new Error("Client already exists")
21 |     }
22 | 
23 |     const client = Object.assign({
24 |       username,
25 |       password,
26 |       id: randomUUID()
27 |     })
28 | 
29 |     this.clients.push(client)
30 | 
31 |     return client
32 |   }
33 |   async find({ id_client }: FindRequestProps): Promise<Clients[]> {
34 |     const clientFound = this.clients.filter((client) => client.id === id_client)
35 | 
36 |     if(!clientFound[0]){
37 |       throw new Error("Client with this id not found")
38 |     }
39 | 
40 |     return clientFound
41 |   }
42 | }
```

--------------------------------------------------------------------------------
/src/database/repositories/ClientRepository.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Clients } from "@prisma/client";
 2 | import { hash } from "bcrypt";
 3 | import { prisma } from "../prismaClient";
 4 | import { CreateRequestProps, FindRequestProps, IClientRepository } from "./interfaces/IClientRepository";
 5 | 
 6 | export class ClientRepository implements IClientRepository {
 7 |   private static INSTANCE: ClientRepository;
 8 | 
 9 |   public static getInstance(): ClientRepository{
10 | 
11 |     if(!ClientRepository.INSTANCE){
12 |       ClientRepository.INSTANCE = new ClientRepository()
13 |     }
14 | 
15 |     return ClientRepository.INSTANCE
16 |   }
17 | 
18 |   async create({ username, password }: CreateRequestProps): Promise<Clients> {
19 |     const hashPassword = await hash(password, 10);
20 | 
21 |     const client = await prisma.clients.create({
22 |       data: {
23 |         password: hashPassword,
24 |         username,
25 |       }
26 |     })
27 | 
28 |     return client
29 |   }
30 |   async find({ id_client }: FindRequestProps): Promise<Clients[]> {
31 |     const client = await prisma.clients.findMany({
32 |       where: {
33 |         id: id_client
34 |       },
35 |       select: {
36 |         id: true,
37 |         username: true,
38 |         Deliveries: true,
39 |         password: true
40 |       }
41 |     })
42 | 
43 |     return client
44 |   }
45 | 
46 | }
```

--------------------------------------------------------------------------------
/src/routes.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Router } from "express";
 2 | import { AuthenticateClientController } from "./modules/account/authenticateClient/AuthenticateClientController";
 3 | import { AuthenticateDeliverymanController } from "./modules/account/authenticateDeliveryman/AuthenticateDeliverymanController";
 4 | import { CreateDeliveryController } from "./modules/deliveries/useCases/createDelivery/CreateDeliveryController";
 5 | import { CreateDeliverymanController } from "./modules/deliveryman/useCases/createDeliveryman/CreateDeliverymanController";
 6 | 
 7 | import { ensureAuthClient } from "./middlewares/ensureAuthClient";
 8 | import { ensureAuthDeliveryman } from "./middlewares/ensureAuthDeliveryman";
 9 | import { FindAllAvailableController } from "./modules/deliveries/useCases/findAllAvailable/FindAllAvailableController";
10 | import { UpdateDeliverymanController } from "./modules/deliveries/useCases/updateDeliveryman/UpdateDeliverymanController";
11 | import { FindAllDeliveriesController } from "./modules/deliveryman/useCases/findAllDeliveries/FindAllDeliveriesController";
12 | import { UpdateEndDateController } from "./modules/deliveries/updateEndDate/UpdateEndDateController";
13 | import { createClientController } from "./modules/clients/useCases/createClient";
14 | import { findClientDeliveriesController } from "./modules/clients/useCases/findClientDeliveries";
15 | 
16 | const routes = Router()
17 | 
18 | const authenticateClientController = new AuthenticateClientController()
19 | 
20 | const createDeliverymanController = new CreateDeliverymanController()
21 | const authenticateDeliverymanController = new AuthenticateDeliverymanController()
22 | const findAllAvailableController = new FindAllAvailableController()
23 | 
24 | const createDeliveryController = new CreateDeliveryController()
25 | const updateDeliverymanController = new UpdateDeliverymanController()
26 | const findAllDeliveriesController = new FindAllDeliveriesController()
27 | const updateEndDateController = new UpdateEndDateController()
28 | 
29 | const authenticateClient = new AuthenticateClientController()
30 | 
31 | 
32 | routes.post("/client", (req, res) => {
33 |   return createClientController.handle(req, res)
34 | })
35 | routes.get("/client/myDeliveries", ensureAuthClient, (req, res) => {
36 |   return findClientDeliveriesController.handle(req, res)
37 | })
38 | routes.post("/client/authenticate", authenticateClientController.handle)
39 | 
40 | routes.post("/deliveryman", createDeliverymanController.handle)
41 | routes.get("/deliveryman/myDeliveries", ensureAuthDeliveryman, findAllDeliveriesController.handle)
42 | routes.post("/deliveryman/authenticate", authenticateDeliverymanController.handle)
43 | routes.put("/deliveryman/authenticate", authenticateDeliverymanController.handle)
44 | 
45 | routes.get("/delivery/available", ensureAuthDeliveryman, findAllAvailableController.handle)
46 | routes.post("/delivery", ensureAuthClient, createDeliveryController.handle)
47 | routes.put("/delivery/updateDeliveryman/:id", ensureAuthDeliveryman, updateDeliverymanController.handle)
48 | routes.put("/delivery/updateEndDate/:id", ensureAuthDeliveryman, updateEndDateController.handle)
49 | 
50 | routes.post('/auth/user', authenticateClient.handle)
51 | 
52 | export { routes }
```

--------------------------------------------------------------------------------
/jest.config.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /*
  2 |  * For a detailed explanation regarding each configuration property and type check, visit:
  3 |  * https://jestjs.io/docs/configuration
  4 |  */
  5 | 
  6 | export default {
  7 |   // All imported modules in your tests should be mocked automatically
  8 |   // automock: false,
  9 | 
 10 |   // Stop running tests after `n` failures
 11 |   // bail: 0,
 12 | 
 13 |   // The directory where Jest should store its cached dependency information
 14 |   // cacheDirectory: "C:\\Users\\rafae\\AppData\\Local\\Temp\\jest",
 15 | 
 16 |   // Automatically clear mock calls, instances, contexts and results before every test
 17 |   clearMocks: true,
 18 | 
 19 |   // Indicates whether the coverage information should be collected while executing the test
 20 |   // collectCoverage: false,
 21 | 
 22 |   // An array of glob patterns indicating a set of files for which coverage information should be collected
 23 |   // collectCoverageFrom: undefined,
 24 | 
 25 |   // The directory where Jest should output its coverage files
 26 |   // coverageDirectory: undefined,
 27 | 
 28 |   // An array of regexp pattern strings used to skip coverage collection
 29 |   // coveragePathIgnorePatterns: [
 30 |   //   "\\\\node_modules\\\\"
 31 |   // ],
 32 | 
 33 |   // Indicates which provider should be used to instrument code for coverage
 34 |   coverageProvider: "v8",
 35 | 
 36 |   // A list of reporter names that Jest uses when writing coverage reports
 37 |   // coverageReporters: [
 38 |   //   "json",
 39 |   //   "text",
 40 |   //   "lcov",
 41 |   //   "clover"
 42 |   // ],
 43 | 
 44 |   // An object that configures minimum threshold enforcement for coverage results
 45 |   // coverageThreshold: undefined,
 46 | 
 47 |   // A path to a custom dependency extractor
 48 |   // dependencyExtractor: undefined,
 49 | 
 50 |   // Make calling deprecated APIs throw helpful error messages
 51 |   // errorOnDeprecated: false,
 52 | 
 53 |   // The default configuration for fake timers
 54 |   // fakeTimers: {
 55 |   //   "enableGlobally": false
 56 |   // },
 57 | 
 58 |   // Force coverage collection from ignored files using an array of glob patterns
 59 |   // forceCoverageMatch: [],
 60 | 
 61 |   // A path to a module which exports an async function that is triggered once before all test suites
 62 |   // globalSetup: undefined,
 63 | 
 64 |   // A path to a module which exports an async function that is triggered once after all test suites
 65 |   // globalTeardown: undefined,
 66 | 
 67 |   // A set of global variables that need to be available in all test environments
 68 |   // globals: {},
 69 | 
 70 |   // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
 71 |   // maxWorkers: "50%",
 72 | 
 73 |   // An array of directory names to be searched recursively up from the requiring module's location
 74 |   // moduleDirectories: [
 75 |   //   "node_modules"
 76 |   // ],
 77 | 
 78 |   // An array of file extensions your modules use
 79 |   // moduleFileExtensions: [
 80 |   //   "js",
 81 |   //   "mjs",
 82 |   //   "cjs",
 83 |   //   "jsx",
 84 |   //   "ts",
 85 |   //   "tsx",
 86 |   //   "json",
 87 |   //   "node"
 88 |   // ],
 89 | 
 90 |   // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
 91 |   // moduleNameMapper: {},
 92 | 
 93 |   // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
 94 |   // modulePathIgnorePatterns: [],
 95 | 
 96 |   // Activates notifications for test results
 97 |   // notify: false,
 98 | 
 99 |   // An enum that specifies notification mode. Requires { notify: true }
100 |   // notifyMode: "failure-change",
101 | 
102 |   // A preset that is used as a base for Jest's configuration
103 |   preset: 'ts-jest',
104 | 
105 |   // Run tests from one or more projects
106 |   // projects: undefined,
107 | 
108 |   // Use this configuration option to add custom reporters to Jest
109 |   // reporters: undefined,
110 | 
111 |   // Automatically reset mock state before every test
112 |   // resetMocks: false,
113 | 
114 |   // Reset the module registry before running each individual test
115 |   // resetModules: false,
116 | 
117 |   // A path to a custom resolver
118 |   // resolver: undefined,
119 | 
120 |   // Automatically restore mock state and implementation before every test
121 |   // restoreMocks: false,
122 | 
123 |   // The root directory that Jest should scan for tests and modules within
124 |   // rootDir: undefined,
125 | 
126 |   // A list of paths to directories that Jest should use to search for files in
127 |   // roots: [
128 |   //   "<rootDir>"
129 |   // ],
130 | 
131 |   // Allows you to use a custom runner instead of Jest's default test runner
132 |   // runner: "jest-runner",
133 | 
134 |   // The paths to modules that run some code to configure or set up the testing environment before each test
135 |   // setupFiles: [],
136 | 
137 |   // A list of paths to modules that run some code to configure or set up the testing framework before each test
138 |   // setupFilesAfterEnv: [],
139 | 
140 |   // The number of seconds after which a test is considered as slow and reported as such in the results.
141 |   // slowTestThreshold: 5,
142 | 
143 |   // A list of paths to snapshot serializer modules Jest should use for snapshot testing
144 |   // snapshotSerializers: [],
145 | 
146 |   // The test environment that will be used for testing
147 |   // testEnvironment: "jest-environment-node",
148 | 
149 |   // Options that will be passed to the testEnvironment
150 |   // testEnvironmentOptions: {},
151 | 
152 |   // Adds a location field to test results
153 |   // testLocationInResults: false,
154 | 
155 |   // The glob patterns Jest uses to detect test files
156 |   testMatch: [
157 |     "**/**/*.spec.ts"
158 |   ],
159 | 
160 |   // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
161 |   // testPathIgnorePatterns: [
162 |   //   "\\\\node_modules\\\\"
163 |   // ],
164 | 
165 |   // The regexp pattern or array of patterns that Jest uses to detect test files
166 |   // testRegex: [],
167 | 
168 |   // This option allows the use of a custom results processor
169 |   // testResultsProcessor: undefined,
170 | 
171 |   // This option allows use of a custom test runner
172 |   // testRunner: "jest-circus/runner",
173 | 
174 |   // A map from regular expressions to paths to transformers
175 |   // transform: undefined,
176 | 
177 |   // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
178 |   // transformIgnorePatterns: [
179 |   //   "\\\\node_modules\\\\",
180 |   //   "\\.pnp\\.[^\\\\]+$"
181 |   // ],
182 | 
183 |   // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
184 |   // unmockedModulePathPatterns: undefined,
185 | 
186 |   // Indicates whether each individual test should be reported during the run
187 |   // verbose: undefined,
188 | 
189 |   // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
190 |   // watchPathIgnorePatterns: [],
191 | 
192 |   // Whether to use watchman for file crawling
193 |   // watchman: true,
194 | };
195 | 
```