Skip to content

Commit 3b99f08

Browse files
authoredOct 26, 2022
Initial commit
0 parents  commit 3b99f08

35 files changed

+18009
-0
lines changed
 

‎.babelrc

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"presets": [
3+
[
4+
"@babel/preset-env",
5+
{
6+
"targets": {
7+
"node": "16"
8+
}
9+
},
10+
],
11+
"@babel/preset-typescript"
12+
],
13+
"plugins": [
14+
[
15+
"module-resolver",
16+
{
17+
"alias": {
18+
"contracts": "./src/contracts",
19+
"infra": "./src/infra",
20+
"usecases": "./src/usecases",
21+
"services": "./src/services",
22+
"controllers": "./src/controllers",
23+
"entities": "./src/entities",
24+
"common": "./src/common"
25+
},
26+
"cwd": "babelrc"
27+
}
28+
]
29+
]
30+
}

‎.env-example

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
MONGODB_URI
2+
RABBITMQ_URI
3+
SERVER_PORT
4+
LOG_LEVEL

‎.eslintrc.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module.exports = {
2+
parser: '@typescript-eslint/parser',
3+
parserOptions: {
4+
project: 'tsconfig.json',
5+
sourceType: 'module',
6+
},
7+
plugins: ['@typescript-eslint/eslint-plugin'],
8+
extends: [
9+
'plugin:@typescript-eslint/recommended',
10+
'plugin:prettier/recommended',
11+
],
12+
root: true,
13+
env: {
14+
node: true,
15+
jest: true,
16+
},
17+
ignorePatterns: ['.eslintrc.js'],
18+
rules: {
19+
'@typescript-eslint/interface-name-prefix': 'off',
20+
'@typescript-eslint/explicit-function-return-type': 'off',
21+
'@typescript-eslint/explicit-module-boundary-types': 'off',
22+
'@typescript-eslint/no-explicit-any': 'off',
23+
},
24+
};
25+

‎.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/dist
2+
/node_modules
3+
/coverage
4+
.env
5+
6+
.vscode/*

‎.prettierrc

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"singleQuote": true,
3+
"trailingComma": "all"
4+
}

‎README.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# scaffold-service
2+
Este é um repositório base com estrutura inicial necessária para a construção dos serviços do projeto `TCC`
3+
___
4+
5+
### Desenvolvimento
6+
Esse app é composto por
7+
- Express.js
8+
- RabbitMQ
9+
- MongoDB
10+
- Jest
11+
12+
### Testes
13+
Executar
14+
> npm run test
15+
16+
### Execução
17+
Executar
18+
> npm run start

‎package-lock.json

+17,313
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
{
2+
"name": "nome",
3+
"version": "0.0.1",
4+
"description": "descricao",
5+
"author": "Indiara Camillo Menegat",
6+
"private": true,
7+
"license": "UNLICENSED",
8+
"scripts": {
9+
"build": "npm run format && npm run lint && tsc --noEmit -p . && rimraf dist && babel src --extensions \".ts,.js\" --out-dir dist --copy-files --no-copy-ignored --source-maps",
10+
"prebuild": "rimraf dist",
11+
"format": "prettier --write \"src/**/*.ts\"",
12+
"start": "node dist/index.js",
13+
"lint": "eslint \"{src,test}/**/*.ts\" --fix",
14+
"test": "jest --runInBand",
15+
"test:watch": "jest --watch",
16+
"test:cov": "jest --coverage",
17+
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand"
18+
},
19+
"dependencies": {
20+
"@types/amqplib": "^0.8.2",
21+
"amqplib": "^0.8.0",
22+
"body-parser": "^1.20.0",
23+
"dotenv": "^16.0.0",
24+
"express": "^4.17.2",
25+
"mongoose": "^6.1.10",
26+
"winston": "^3.7.2"
27+
},
28+
"engines": {
29+
"node": "16"
30+
},
31+
"devDependencies": {
32+
"@babel/cli": "^7.17.10",
33+
"@babel/core": "^7.17.12",
34+
"@babel/node": "^7.17.10",
35+
"@babel/preset-env": "^7.17.12",
36+
"@babel/preset-typescript": "^7.17.12",
37+
"@types/express": "^4.17.13",
38+
"@types/jest": "27.0.2",
39+
"@types/node": "^16.0.0",
40+
"@typescript-eslint/eslint-plugin": "^5.0.0",
41+
"@typescript-eslint/parser": "^5.0.0",
42+
"babel-plugin-module-resolver": "^4.1.0",
43+
"eslint": "^8.0.1",
44+
"eslint-config-prettier": "^8.3.0",
45+
"eslint-plugin-prettier": "^4.0.0",
46+
"jest": "^27.2.5",
47+
"prettier": "^2.3.2",
48+
"ts-jest": "^27.0.3",
49+
"ts-loader": "^9.2.3",
50+
"ts-node": "^10.7.0",
51+
"tsconfig-paths": "^3.10.1",
52+
"typescript": "^4.3.5"
53+
},
54+
"jest": {
55+
"moduleFileExtensions": [
56+
"js",
57+
"json",
58+
"ts"
59+
],
60+
"rootDir": "src",
61+
"testRegex": ".*\\.spec\\.ts$",
62+
"transform": {
63+
"^.+\\.(t|j)s$": "ts-jest"
64+
},
65+
"collectCoverageFrom": [
66+
"**/*.(t|j)s"
67+
],
68+
"coverageDirectory": "../coverage",
69+
"testEnvironment": "node"
70+
}
71+
}

‎src/common/errors/HttpError.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { IHttpError } from 'contracts/server/Http';
2+
3+
export class HttpError implements IHttpError {
4+
readonly status: number;
5+
readonly message: string;
6+
7+
constructor(props: IHttpError) {
8+
this.status = props.status;
9+
this.message = props.message;
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { HttpRequest, HttpResponse } from 'contracts/server/Http';
2+
import { BaseUseCase } from 'contracts/usecases/BaseUseCase';
3+
4+
export interface BaseController {
5+
useCase: BaseUseCase;
6+
handle: (request: HttpRequest) => Promise<HttpResponse>;
7+
}

‎src/contracts/entities/ITest.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface ITest {
2+
value: number;
3+
word: string;
4+
isItTrue: boolean;
5+
}

‎src/contracts/server/Http.ts

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export interface Query {
2+
[key: string]: undefined | string | string[] | Query | Query[];
3+
}
4+
5+
export interface HttpRequest {
6+
headers?: Record<string, string | string[] | undefined>;
7+
params?: Record<string, string>;
8+
query?: Query;
9+
body?: any;
10+
}
11+
12+
export interface HttpResponse {
13+
status: number;
14+
body?: unknown;
15+
}
16+
17+
export interface IHttpError {
18+
status: number;
19+
message: string;
20+
}

‎src/contracts/usecases/BaseUseCase.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export interface BaseUseCase {
2+
execute: (input: any) => Promise<void>;
3+
}

‎src/controllers/TestController.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { HttpError } from 'common/errors/HttpError';
2+
import { BaseController } from 'contracts/controllers/BaseController';
3+
import { ITest } from 'contracts/entities/ITest';
4+
import { HttpRequest, HttpResponse } from 'contracts/server/Http';
5+
import { TestUseCase } from 'usecases/TestUseCase';
6+
7+
export class TestController implements BaseController {
8+
readonly useCase: TestUseCase;
9+
constructor(useCase: TestUseCase) {
10+
this.useCase = useCase;
11+
}
12+
13+
async handle(request: HttpRequest): Promise<HttpResponse> {
14+
try {
15+
const input: ITest = {
16+
isItTrue: request.body?.isItTrue || true,
17+
value: request.body?.value || 100,
18+
word: request.body?.word || 'banana',
19+
};
20+
await this.useCase.execute(input);
21+
return {
22+
status: 200,
23+
body: 'everything is great!',
24+
};
25+
} catch (error) {
26+
throw new HttpError({
27+
message: 'Error while etc etc',
28+
status: 400,
29+
});
30+
}
31+
}
32+
}

‎src/entities/Test.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { ITest } from 'contracts/entities/ITest';
2+
3+
export class Test implements ITest {
4+
readonly value: number;
5+
readonly word: string;
6+
readonly isItTrue: boolean;
7+
8+
constructor(props: ITest) {
9+
this.value = props.value;
10+
this.word = props.word;
11+
this.isItTrue = props.isItTrue;
12+
}
13+
}

‎src/index.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { default as Database } from 'infra/database/Connection';
2+
import { default as Broker } from 'infra/message-broker/Manager';
3+
import { default as Server } from 'infra/server/Server';
4+
import { TestPublisher } from './infra/message-broker/publishers/TestPublisher';
5+
6+
(async () => {
7+
Promise.all([Database.init(), Broker.init(), Server.init()]).then(
8+
async () => {
9+
const test = new TestPublisher();
10+
test.publish(
11+
JSON.stringify({
12+
word: 'mensgaem enviada',
13+
isItTrue: false,
14+
value: 654,
15+
}),
16+
);
17+
},
18+
);
19+
})();

‎src/infra/config.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import * as dotenv from 'dotenv';
2+
dotenv.config();
3+
4+
export abstract class Config {
5+
static readonly mongoURI = process.env.MONGODB_URI;
6+
static readonly rabbitURI = process.env.RABBITMQ_URI;
7+
static readonly serverPort = process.env.SERVER_PORT || 3000;
8+
static readonly logLevel = process.env.LOG_LEVEL || 'info';
9+
static readonly exchanges = [
10+
{
11+
name: 'test',
12+
type: 'topic',
13+
routingKeys: ['teste.key'],
14+
},
15+
];
16+
}

‎src/infra/database/Connection.ts

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { connect, connection } from 'mongoose';
2+
import { Config } from '../config';
3+
import { logger } from '../logger';
4+
5+
class Database {
6+
public readonly uri: string = Config.mongoURI;
7+
8+
async init(): Promise<void> {
9+
try {
10+
connection.on('disconnected', async () => {
11+
logger.info('Trying to connect database again');
12+
await connect(this.uri);
13+
});
14+
15+
connection.on('error', async () => {
16+
logger.error('Error connecting to database');
17+
process.exit();
18+
});
19+
20+
logger.info('Connecting to database with uri %s', this.uri);
21+
await connect(this.uri);
22+
} catch (error) {
23+
logger.error('Error while connecting to database: %s', error.message);
24+
throw error;
25+
}
26+
}
27+
}
28+
29+
export default new Database();

‎src/infra/database/SchemaOptions.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { SchemaOptions } from 'mongoose';
2+
3+
export const schemaOptions: SchemaOptions = {
4+
versionKey: false,
5+
timestamps: {
6+
createdAt: 'createdAt',
7+
updatedAt: 'updatedAt',
8+
},
9+
};
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { ITest } from 'contracts/entities/ITest';
2+
import { model, Schema } from 'mongoose';
3+
import { schemaOptions } from '../SchemaOptions';
4+
5+
export const TestSchema = new Schema<ITest>(
6+
{
7+
value: {
8+
type: Number,
9+
default: 0,
10+
},
11+
word: {
12+
type: String,
13+
required: true,
14+
},
15+
isItTrue: {
16+
type: Boolean,
17+
},
18+
},
19+
schemaOptions,
20+
);
21+
22+
export const TestModel = model<ITest>('Test', TestSchema);

‎src/infra/logger.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { createLogger, transports, format } from 'winston';
2+
import { Config } from './config';
3+
4+
export const logger = createLogger({
5+
level: Config.logLevel,
6+
transports: [new transports.Console()],
7+
format: format.combine(
8+
format.colorize(),
9+
format.splat(),
10+
format.metadata(),
11+
format.timestamp(),
12+
format.printf(({ timestamp, level, message, metadata }) => {
13+
return `[${timestamp}] ${level}: ${message}. ${JSON.stringify(metadata)}`;
14+
}),
15+
),
16+
});

‎src/infra/message-broker/Manager.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import client, { Channel, Connection } from 'amqplib';
2+
import { Config } from '../config';
3+
import { logger } from '../logger';
4+
import { initSubscribers } from './subscribers';
5+
6+
class MessageBroker {
7+
private readonly uri: string = Config.rabbitURI;
8+
private readonly exchanges = Config.exchanges;
9+
connection: Connection;
10+
channel: Channel;
11+
12+
async init(): Promise<void> {
13+
try {
14+
logger.info('Connecting to message broker');
15+
this.connection = await client.connect(this.uri, { heartbeat: 60 });
16+
17+
this.channel = await this.connection.createChannel();
18+
19+
Promise.all(
20+
this.exchanges.map((exchange) =>
21+
this.channel.assertExchange(exchange.name, exchange.type, {
22+
durable: true,
23+
}),
24+
),
25+
).then(() => initSubscribers());
26+
27+
logger.info('Connected to message broker');
28+
} catch (error) {
29+
logger.error('Error while starting message broker: $s', error);
30+
throw error;
31+
}
32+
}
33+
}
34+
35+
export default new MessageBroker();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { logger } from 'infra/logger';
2+
import { default as MessageBroker } from 'infra/message-broker/Manager';
3+
4+
export class BasePublisher {
5+
constructor(
6+
protected exchange: { name: string; type: string },
7+
protected routingKey: string,
8+
) {}
9+
10+
publish(msg: string): void {
11+
const channel = MessageBroker.channel;
12+
const content = Buffer.from(msg);
13+
channel.publish(this.exchange.name, this.routingKey, content);
14+
logger.info('Message published', {
15+
exchange: this.exchange,
16+
routingKey: this.routingKey,
17+
});
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Config } from 'infra/config';
2+
import { BasePublisher } from './BasePublisher';
3+
4+
export class TestPublisher extends BasePublisher {
5+
constructor() {
6+
const exchange = {
7+
name: Config.exchanges[0].name,
8+
type: Config.exchanges[0].type,
9+
};
10+
const routingKey = Config.exchanges[0].routingKeys[0];
11+
super(exchange, routingKey);
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { ConsumeMessage } from 'amqplib';
2+
import { BaseUseCase } from 'contracts/usecases/BaseUseCase';
3+
import { logger } from 'infra/logger';
4+
import { default as MessageBroker } from 'infra/message-broker/Manager';
5+
6+
export class BaseSubscriber {
7+
constructor(
8+
private exchange: { name: string; type: string },
9+
private routingKey: string,
10+
private useCase: BaseUseCase,
11+
) {}
12+
13+
async consume(): Promise<void> {
14+
const channel = MessageBroker.channel;
15+
const queueName = `${this.routingKey}_queue`;
16+
17+
Promise.all([
18+
channel.assertQueue(queueName),
19+
channel.bindQueue(queueName, this.exchange.name, this.routingKey),
20+
channel.prefetch(1),
21+
channel.consume(queueName, (msg: ConsumeMessage) => {
22+
if (msg.content) {
23+
const parsedData = JSON.parse(msg.content.toString());
24+
logger.info('Message consumed', {
25+
exchange: this.exchange,
26+
routingKey: this.routingKey,
27+
content: parsedData,
28+
});
29+
this.useCase.execute(parsedData).then(() => channel.ack(msg));
30+
}
31+
}),
32+
]).catch((reason) => {
33+
logger.error('Error while consuming message', {
34+
exchange: this.exchange,
35+
routingKey: this.routingKey,
36+
});
37+
throw new Error(reason);
38+
});
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Config } from 'infra/config';
2+
import { TestService } from 'services/TestService';
3+
import { TestUseCase } from 'usecases/TestUseCase';
4+
import { BaseSubscriber } from './BaseSubscriber';
5+
6+
class TestSubscriber extends BaseSubscriber {
7+
constructor() {
8+
const exchange = {
9+
name: Config.exchanges[0].name,
10+
type: Config.exchanges[0].type,
11+
};
12+
const routingKey = Config.exchanges[0].routingKeys[0];
13+
const service = new TestService();
14+
const useCase = new TestUseCase(service);
15+
super(exchange, routingKey, useCase);
16+
}
17+
}
18+
19+
export default new TestSubscriber();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/** Neste arquivo serão importados todos os subscribers criados e
2+
* será configurado para que ouçam uma determinada exchange/queue/routinKey*/
3+
4+
import { default as TestSubscriber } from './TestSubscriber';
5+
6+
export const initSubscribers = (): Promise<void>[] => {
7+
return [TestSubscriber.consume()];
8+
};

‎src/infra/server/Middlewares.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { HttpError } from 'common/errors/HttpError';
2+
import { BaseController } from 'contracts/controllers/BaseController';
3+
import { Request, Response, NextFunction, RequestHandler } from 'express';
4+
5+
export const requestHandlerMidd = (
6+
controller: BaseController,
7+
): RequestHandler => {
8+
return async (req: Request, res: Response, next: NextFunction) => {
9+
try {
10+
const httpResponse = await controller.handle(req);
11+
res.status(httpResponse.status).json(httpResponse.body);
12+
} catch (error) {
13+
if (error instanceof HttpError)
14+
return res.status(error.status).send(error.message);
15+
16+
return res
17+
.status(500)
18+
.send('An internal error occourred, try again later');
19+
} finally {
20+
next();
21+
}
22+
};
23+
};

‎src/infra/server/Routes.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/** Arquivo pra cadastrar rotas caso exista um server */
2+
import { Express } from 'express';
3+
import { default as TestRouter } from './routes/TestRouter';
4+
5+
export const initRoutes = (app: Express) => {
6+
app.use('/test', TestRouter);
7+
};

‎src/infra/server/Server.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import bodyParser from 'body-parser';
2+
import express, { Express } from 'express';
3+
import { Config } from 'infra/config';
4+
import { logger } from 'infra/logger';
5+
import { initRoutes } from './Routes';
6+
7+
class Server {
8+
readonly app: Express = express();
9+
readonly port = Config.serverPort;
10+
11+
async init(): Promise<void> {
12+
this.app.use(express.json());
13+
this.app.use(bodyParser.json({ limit: '50mb' }));
14+
15+
this.app.listen(this.port, () => {
16+
logger.info('Server running on port ' + this.port);
17+
});
18+
19+
initRoutes(this.app);
20+
}
21+
}
22+
23+
export default new Server();

‎src/infra/server/routes/TestRouter.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { TestController } from 'controllers/TestController';
2+
import { Router } from 'express';
3+
import { TestService } from 'services/TestService';
4+
import { TestUseCase } from 'usecases/TestUseCase';
5+
import { requestHandlerMidd } from '../Middlewares';
6+
7+
const router = Router();
8+
9+
router.get(
10+
'/send-message',
11+
requestHandlerMidd(new TestController(new TestUseCase(new TestService()))),
12+
);
13+
14+
export default router;

‎src/services/BaseService.ts

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { logger } from 'infra/logger';
2+
import { HydratedDocument, Model, FilterQuery, UpdateQuery } from 'mongoose';
3+
4+
export class BaseService<T> {
5+
protected readonly model: Model<T>;
6+
7+
constructor(model: Model<T>) {
8+
this.model = model;
9+
}
10+
11+
async create(data: T): Promise<HydratedDocument<T>> {
12+
try {
13+
return this.model.create(data);
14+
} catch (error) {
15+
logger.error('Error while creating document on database', {
16+
name: this.model.modelName,
17+
data,
18+
});
19+
}
20+
}
21+
22+
async update(query: FilterQuery<T>, update: UpdateQuery<T>): Promise<void> {
23+
try {
24+
await this.model.updateMany(query, update);
25+
} catch (error) {
26+
logger.error('Error while updating document on database', {
27+
name: this.model.modelName,
28+
query,
29+
update,
30+
});
31+
}
32+
}
33+
34+
async find(query: FilterQuery<T>): Promise<T[]> {
35+
try {
36+
return await this.model.find(query).lean();
37+
} catch (error) {
38+
logger.error('Error while trying to find documents on database', {
39+
name: this.model.modelName,
40+
query,
41+
});
42+
}
43+
}
44+
45+
async delete(query: FilterQuery<T>): Promise<void> {
46+
try {
47+
await this.model.deleteMany(query);
48+
} catch (error) {
49+
logger.error('Error while deleting documents on database', {
50+
name: this.model.modelName,
51+
query,
52+
});
53+
}
54+
}
55+
}

‎src/services/TestService.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { ITest } from 'contracts/entities/ITest';
2+
import { TestModel } from 'infra/database/schemas/TestSchema';
3+
import { BaseService } from './BaseService';
4+
5+
export class TestService extends BaseService<ITest> {
6+
constructor() {
7+
super(TestModel);
8+
}
9+
}

‎src/usecases/TestUseCase.ts

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { ITest } from 'contracts/entities/ITest';
2+
import { BaseUseCase } from 'contracts/usecases/BaseUseCase';
3+
import { Test } from 'entities/Test';
4+
import { TestService } from 'services/TestService';
5+
6+
export class TestUseCase implements BaseUseCase {
7+
constructor(private readonly testService: TestService) {}
8+
9+
async execute(input: ITest): Promise<void> {
10+
console.log('Printing message', input);
11+
12+
const entity = new Test(input);
13+
14+
const createdObjs = await Promise.all([
15+
this.testService.create(entity),
16+
this.testService.create(entity),
17+
this.testService.create(entity),
18+
]);
19+
20+
console.log(createdObjs);
21+
22+
console.log(`Deletando com id ${createdObjs[0]._id}`);
23+
await this.testService.delete({
24+
_id: createdObjs[0]._id,
25+
});
26+
27+
console.log(`Atualizando com id ${createdObjs[1]._id}`);
28+
await this.testService.update(
29+
{
30+
_id: createdObjs[1]._id,
31+
},
32+
{
33+
$set: { isItTrue: false, value: 1000000 },
34+
},
35+
);
36+
37+
const returned = await this.testService.find({ value: 654 });
38+
console.log(returned);
39+
}
40+
}

‎tsconfig.json

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"compilerOptions": {
3+
"module": "commonjs",
4+
"declaration": true,
5+
"removeComments": true,
6+
"emitDecoratorMetadata": true,
7+
"experimentalDecorators": true,
8+
"allowSyntheticDefaultImports": true,
9+
"target": "es2017",
10+
"sourceMap": true,
11+
"outDir": "./dist",
12+
"baseUrl": "./",
13+
"incremental": true,
14+
"skipLibCheck": true,
15+
"strictNullChecks": false,
16+
"noImplicitAny": false,
17+
"strictBindCallApply": false,
18+
"forceConsistentCasingInFileNames": false,
19+
"noFallthroughCasesInSwitch": false,
20+
"resolveJsonModule": true,
21+
"paths": {
22+
"common/*":["src/common/*"],
23+
"contracts/*":["src/contracts/*"],
24+
"controllers/*":["src/controllers/*"],
25+
"entities/*":["src/entities/*"],
26+
"infra/*":["src/infra/*"],
27+
"services/*":["src/services/*"],
28+
"usecases/*":["src/usecases/*"],
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)
Please sign in to comment.