Skip to content

Commit

Permalink
feat: add DTO to products and cart memory DAO and Reposotory pattern …
Browse files Browse the repository at this point in the history
…to messages
  • Loading branch information
joxpulp committed Nov 30, 2021
1 parent b0778d8 commit 104927e
Show file tree
Hide file tree
Showing 18 changed files with 9,442 additions and 8,792 deletions.
17,899 changes: 9,126 additions & 8,773 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"mongoose": "^6.0.6",
"mysql": "^2.18.1",
"regenerator-runtime": "^0.13.9",
"socket.io": "^4.4.0",
"sqlite3": "^5.0.2"
}
}
22 changes: 22 additions & 0 deletions src/apis/messagesapi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Messages } from '../models/interfaces';
import { flags } from '../config/config';
import { MessagesFactoryDAO } from '../models/messages/messagesFactory';

class messagesAPI {
private messages;

constructor() {
this.messages = MessagesFactoryDAO.get(flags.D);
}

async getMessages(): Promise<Messages[]> {
return await this.messages.find();
}

async addMessage(data: Messages): Promise<Messages> {
const newMessage = await this.messages.add(data);
return newMessage;
}
}

export const messageAPI = new messagesAPI();
28 changes: 28 additions & 0 deletions src/baseRepository/memoria.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { IReadMem, IWriteMem } from '../models/interfaces';

export abstract class BaseMem<T> implements IReadMem<T>, IWriteMem<T> {
content: T[];

constructor() {
this.content = [];
}

randomId(): string {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}

find(): T[] {
return this.content;
}

add(item: T): T {
const newMessage: T = {
_id: this.randomId(),
...item,
};
this.content.push(newMessage);
return newMessage;
}
}
39 changes: 39 additions & 0 deletions src/baseRepository/mongodb.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Schema, model, connect } from 'mongoose';
import { IRead, IWrite, Messages } from '../models/interfaces';
import CONFIG from '../config/config';

const messagesCollection = 'mensajes';

const messagesSchema = new Schema<Messages>(
{
email: { type: String, required: true, max: 100 },
message: { type: String, required: true, max: 100 },
},
{ versionKey: false }
);

export const messages = model<Messages>(messagesCollection, messagesSchema);

export abstract class BaseMongo<T> implements IRead<T>, IWrite<T> {
private uri: string;
private messages;

constructor() {
this.uri = `mongodb+srv://${CONFIG.MONGO_USER}:${CONFIG.MONGO_PASSWORD}@${CONFIG.MONGO_ATLAS_CLUSTER}/${CONFIG.MONGO_DBNAME}?retryWrites=true&w=majority`;
connect(this.uri);
this.messages = model<Messages>(messagesCollection, messagesSchema);
}

async find(): Promise<Messages[]> {
let outputGet: Messages[] = [];
const product = await this.messages.find();
outputGet.push(...product)
return outputGet;
}

async add(item: T): Promise<Messages> {
const newProduct = new this.messages(item);
await newProduct.save();
return newProduct;
}
}
39 changes: 39 additions & 0 deletions src/controllers/messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Request, Response } from 'express';
import { messageAPI } from '../apis/messagesapi';

class MessageController {
async getMessages(req: Request, res: Response) {
try {
const getMessages = await messageAPI.getMessages();

if (!getMessages.length)
return res.status(404).json({ error: 'No hay mensajes cargados' });

return res.json({ messages: getMessages });
} catch (error) {
if (error instanceof Error) {
let errorMessage = error.message;
res.status(500).json({ error: errorMessage });
}
}
}
async addMessage(req: Request, res: Response) {
try {
const { email, message } = req.body;

if (!email || !message)
return res.status(404).json({ error: 'Body invalido' });

const newMessage = await messageAPI.addMessage({ email, message });

return res.json({ message: newMessage });
} catch (error) {
if (error instanceof Error) {
let errorMessage = error.message;
res.status(500).json({ error: errorMessage });
}
}
}
}

export const messageController = new MessageController();
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Server from './services/server';
import { ioServer } from './services/socket';

const port = process.env.PORT || 8080;

ioServer(Server);
Server.listen(port, () => console.log(`Server running in port: ${port}`));
Server.on('error', (error) => console.error(`There was an error: ${error}`));
13 changes: 7 additions & 6 deletions src/models/cart/DAO/memoria.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Cart, Products } from '../../interfaces';
import { productsAPI } from '../../../apis/productsapi';
import CartDTO from '../DTO/cart';
export class CartDAOMEM {
// Private instance of the class to use singleton pattern
private static _instance: CartDAOMEM;
Expand Down Expand Up @@ -37,7 +38,7 @@ export class CartDAOMEM {
get(id?: string): Cart[] | Products[] {
// If id exist filter product by id, else return the whole cart's array
const result = id
? this.content[0].products.filter((product) => product._id === id)
? this.content[0].products.filter((product) => product.id === id)
: this.content;
return result;
}
Expand All @@ -47,24 +48,24 @@ export class CartDAOMEM {
const getProducts = await productsAPI.getProducts();

// Filtering a single product from product file by passed id
const newProduct = getProducts.filter((product) => product._id === id);
const [newProduct] = getProducts.filter((product) => product.id === id);

// Pushing the filtered product into the cart's products array
this.content[0].products.push(...newProduct);
this.content[0].products.push(new CartDTO(newProduct));

// Return an empty array if the product does not exist, else return the array with the matched product
return newProduct.length === 0 ? [] : newProduct;
return this.content[0].products.length === 0 ? [] : [newProduct];
}

delete(id: string): Products[] {
// Mapping a new array by id if exists returns an the id else returns -1
const arrayPosition: number = this.content[0].products
.map((product) => product._id)
.map((product) => product.id)
.indexOf(id);

// Filtering the deleted product into a new Array
const deletedProduct = this.content[0].products.filter(
(product) => product._id == id
(product) => product.id == id
);

// If the product exists, remove the product from the cart's products array
Expand Down
24 changes: 24 additions & 0 deletions src/models/cart/DTO/cart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Products } from '../../interfaces';

export default class CartDTO {
id: string;
title: string;
description: string;
code: string;
price: number;
thumbnail: string;
stock: number;
FyH: string;

constructor(data: Products) {
this.id = data.id!;
this.title = data.title!;
this.description = data.description!;
this.code = data.code!;
this.price = data.price!;
this.thumbnail = data.thumbnail!;
this.stock = data.stock!;
this.FyH = new Date().toLocaleString();
}

}
24 changes: 22 additions & 2 deletions src/models/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
export interface IReadMem<T> {
find(item: T): T[];
}
export interface IWriteMem<T> {
add(item: T): T;
}
export interface IRead<T> {
find(item: T): Promise<Messages[]>;
}
export interface IWrite<T> {
add(item: T): Promise<Messages>;
}

export enum Table {
Products = 'productos',
Cart = 'carrito'
Cart = 'carrito',
}

export interface ProductsCart {
Expand All @@ -15,7 +28,7 @@ export interface Cart {
cartProducts?: any;
}
export interface Products {
_id: string;
_id?: string;
id?: string;
title?: string;
description?: string;
Expand Down Expand Up @@ -44,3 +57,10 @@ export interface ProductQuery {
stockMax?: number;
stockMin?: number;
}

export interface Messages {
id?: string;
_id?: string;
email: string;
message: string;
}
19 changes: 19 additions & 0 deletions src/models/messages/DAO/memoria.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Messages } from '../../interfaces';
import { BaseMem } from '../../../baseRepository/memoria';
export class MessagesDAOMEM extends BaseMem<Messages> {
// Private instance of the class to use singleton pattern
private static _instance: MessagesDAOMEM;

// Getter to call the instance with singleton pattern.
public static get instance() {
if (this._instance) {
console.log(
'La instancia MEMORIA MESSAGES ya fue inicializada, se retorna la misma instancia que ya fue inicializada'
);
return this._instance;
} else {
console.log('Instancia MEMORIA MESSAGES inicializada por primera vez');
return (this._instance = new this());
}
}
}
22 changes: 22 additions & 0 deletions src/models/messages/DAO/mongodb.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { BaseMongo } from '../../../baseRepository/mongodb';
import { Messages } from '../../interfaces';

export class MessageDAOMONGO extends BaseMongo<Messages> {
// Private instance of the class to use singleton pattern
private static _instance: MessageDAOMONGO;

// Getter to call the instance with singleton pattern.
public static get instance() {
if (this._instance) {
console.log(
'La instancia MONGODB ATLAS MESSAGES ya fue inicializada, se retorna la misma instancia que ya fue inicializada'
);
return this._instance;
} else {
console.log(
'Intancia MONGODB ATLAS MESSAGES inicializada por primera vez'
);
return (this._instance = new this());
}
}
}
15 changes: 15 additions & 0 deletions src/models/messages/messagesFactory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { MessagesDAOMEM } from './DAO/memoria';
import { MessageDAOMONGO } from './DAO/mongodb';

export class MessagesFactoryDAO {
static get(tipo: string) {
switch (tipo) {
case 'MEMORIA':
return MessagesDAOMEM.instance;
case 'MONGOATLAS':
return MessageDAOMONGO.instance;
default:
return MessagesDAOMEM.instance;
}
}
}
18 changes: 7 additions & 11 deletions src/models/products/DAO/memoria.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Products, newProductI, ProductQuery } from '../../interfaces';
import ProductsDTO from '../DTO/products';

export class ProductDAOMEM {
// Private instance of the class to use singleton pattern
Expand All @@ -22,28 +23,21 @@ export class ProductDAOMEM {
}
}

randomId(): string {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}

finIndex(id: string): number {
return this.content.map((product) => product._id).indexOf(id);
return this.content.map((product) => product.id).indexOf(id);
}

get(id?: string): Products[] {
return id
? this.content.filter((product) => product._id === id)
? this.content.filter((product) => product.id === id)
: this.content;
}

add(data: newProductI): Products {
const newProduct: Products = {
_id: this.randomId(),
...data,
};
this.content.push(newProduct);
this.content.push(new ProductsDTO(newProduct));
return newProduct;
}

Expand All @@ -61,7 +55,9 @@ export class ProductDAOMEM {

delete(id: string): Products[] {
const arrayPosition = this.finIndex(id);
const deletedProduct = this.content.filter((product) => product._id == id);
const deletedProduct = this.content.filter(
(product) => product.id == id
);
arrayPosition !== -1 && this.content.splice(arrayPosition, 1);
return arrayPosition !== -1 ? deletedProduct : [];
}
Expand Down
29 changes: 29 additions & 0 deletions src/models/products/DTO/products.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Products } from "../../interfaces";

export default class ProductsDTO {
id: string;
title: string;
description: string;
code: string;
price: number;
thumbnail: string;
stock: number;
FyH: string;

constructor(data: Products) {
this.id = this.randomId();
this.title = data.title!;
this.description = data.description!;
this.code = data.code!;
this.price = data.price!;
this.thumbnail = data.thumbnail!;
this.stock = data.stock!;
this.FyH = new Date().toLocaleString();
}

randomId(): string {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
}
Loading

0 comments on commit 104927e

Please sign in to comment.