Repository navigation
Implement DTOs and validations; fix vulnerabilities with npm audit #45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
6076083
Se hizo un npm audit para arreglo de vulnerabilidades, se instaló zod…
CrisNAC 5077124
OM-273: 1º avance: Creando DTOs y validaciones de prueba
CrisNAC a04bcac
Merge branch 'dev' into OM-273
CrisNAC 48b145a
OM-273: Cambios por npm audit fix --force
CrisNAC 52f54d7
OM-273: Todoos los DTOs que se van a usar
CrisNAC 730eeb2
Merge branch 'dev' into OM-273
CrisNAC 24e1fbd
OM-273: Correcciones de CodeRabbit v1
CrisNAC 4356823
OM-273: Correcciones de CodeRabbit v2
CrisNAC c07a82a
OM-273: Correcciones de CodeRabbit v3
CrisNAC File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| // This file was generated by Prisma, and assumes you have installed the following: | ||
| // npm install --save-dev prisma dotenv | ||
| import "dotenv/config"; | ||
| import { defineConfig } from "prisma/config"; | ||
|
|
||
| const directUrl = process.env["DIRECT_URL"]; | ||
| if (!directUrl) { | ||
| throw new Error("La variable de entorno DIRECT_URL es requerida y no está definida"); | ||
| } | ||
|
|
||
| export default defineConfig({ | ||
| schema: "prisma/schema.prisma", | ||
| migrations: { | ||
| path: "prisma/migrations", | ||
| }, | ||
| datasource: { | ||
| url: directUrl, | ||
| }, | ||
| }); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| import { Request, Response, NextFunction } from "express"; | ||
| import { ZodSchema, ZodError } from "zod"; | ||
|
|
||
| type RequestSection = "body" | "query" | "params"; | ||
|
|
||
| export const validate = | ||
| (schema: ZodSchema, section: RequestSection = "body") => | ||
| (req: Request, res: Response, next: NextFunction): void => { | ||
| const result = schema.safeParse(req[section]); | ||
|
|
||
| if (!result.success) { | ||
| const errors = result.error.issues.map((e) => ({ | ||
| field: e.path.join("."), | ||
| message: e.message | ||
| })); | ||
|
|
||
| res.status(400).json({ | ||
| message: "Error de validación", | ||
| errors | ||
| }); | ||
| return; | ||
| } | ||
|
|
||
| // Reemplaza el valor original con el dato ya parseado y transformado por Zod | ||
| req[section] = result.data as any; | ||
| next(); | ||
| }; |
File renamed without changes.
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,140 @@ | ||
| import { z } from "zod"; | ||
| import { BaseResponseDTO } from "../base/base.response.dto.js"; | ||
|
|
||
| // ─── REQUEST ───────────────────────────────────────────────────── | ||
| export const CreateAddressDTO = z.object({ | ||
| fk_user: z | ||
| .number({ error: "fk_user es requerido" }) | ||
| .int() | ||
| .positive("fk_user debe ser un ID válido"), | ||
|
|
||
| fk_store: z | ||
| .number() | ||
| .int() | ||
| .positive("fk_store debe ser un ID válido") | ||
| .nullable() | ||
| .optional(), | ||
|
|
||
| address: z | ||
| .string({ error: "address es requerido" }) | ||
| .trim() | ||
| .min(1, "address no puede estar vacío") | ||
| .max(500, "address no puede superar 500 caracteres"), | ||
|
|
||
| city: z | ||
| .string({ error: "city es requerido" }) | ||
| .trim() | ||
| .min(1, "city no puede estar vacío") | ||
| .max(100, "city no puede superar 100 caracteres"), | ||
|
|
||
| region: z | ||
| .string({ error: "region es requerida" }) | ||
| .trim() | ||
| .min(1, "region no puede estar vacía") | ||
| .max(100, "region no puede superar 100 caracteres"), | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| postal_code: z | ||
| .string() | ||
| .trim() | ||
| .max(20, "postal_code no puede superar 20 caracteres") | ||
| .nullable() | ||
| .optional() | ||
| }); | ||
|
|
||
| export type CreateAddressDTOType = z.infer<typeof CreateAddressDTO>; | ||
|
|
||
| export const UpdateAddressDTO = z | ||
| .object({ | ||
| address: z | ||
| .string() | ||
| .trim() | ||
| .min(1, "address no puede estar vacío") | ||
| .max(500, "address no puede superar 500 caracteres").optional(), | ||
|
|
||
| city: z | ||
| .string() | ||
| .trim() | ||
| .min(1, "city no puede estar vacío") | ||
| .max(100, "city no puede superar 100 caracteres") | ||
| .optional(), | ||
|
|
||
| region: z | ||
| .string() | ||
| .trim() | ||
| .min(1, "region no puede estar vacía") | ||
| .max(100, "region no puede superar 100 caracteres") | ||
| .optional(), | ||
|
|
||
| postal_code: z | ||
| .string() | ||
| .trim() | ||
| .max(20, "postal_code no puede superar 20 caracteres") | ||
| .nullable() | ||
| .optional() | ||
| }) | ||
| .refine((data) => Object.values(data).some((v) => v !== undefined), { | ||
| message: "Debe enviar al menos un campo para actualizar" | ||
| }); | ||
|
|
||
| export type UpdateAddressDTOType = z.infer<typeof UpdateAddressDTO>; | ||
|
|
||
| export const FilterAddressDTO = z.object({ | ||
| fk_user: z | ||
| .string() | ||
| .transform(Number) | ||
| .pipe(z.number().int().positive("fk_user debe ser un ID válido")) | ||
| .optional(), | ||
|
|
||
| city: z.string().trim().optional(), | ||
| region: z.string().trim().optional(), | ||
|
|
||
| page: z | ||
| .string() | ||
| .transform(Number) | ||
| .pipe(z.number().int().positive("page debe ser mayor a 0")) | ||
| .optional() | ||
| .default(1), | ||
|
|
||
| limit: z | ||
| .string() | ||
| .transform(Number) | ||
| .pipe(z.number().int().min(1).max(100, "limit no puede superar 100")) | ||
| .optional() | ||
| .default(10) | ||
| }); | ||
|
|
||
| export type FilterAddressDTOType = z.infer<typeof FilterAddressDTO>; | ||
|
|
||
| // ─── RESPONSE ──────────────────────────────────────────────────── | ||
| export class AddressResponseDTO extends BaseResponseDTO { | ||
| id_address: number; | ||
| fk_user: number; | ||
| fk_store: number | null; | ||
| address: string; | ||
| city: string; | ||
| region: string; | ||
| postal_code: string | null; | ||
|
|
||
| constructor(data: any) { | ||
| super({ | ||
| id: data.id_address, | ||
| created_at: data.created_at, | ||
| updated_at: data.updated_at | ||
| }); | ||
| this.id_address = data.id_address; | ||
| this.fk_user = data.fk_user; | ||
| this.fk_store = data.fk_store ?? null; | ||
| this.address = data.address; | ||
| this.city = data.city; | ||
| this.region = data.region; | ||
| this.postal_code = data.postal_code ?? null; | ||
| } | ||
|
|
||
| static map(data: any): AddressResponseDTO { | ||
| return new AddressResponseDTO(data); | ||
| } | ||
|
|
||
| static mapList(data: any[]): AddressResponseDTO[] { | ||
| return data.map(AddressResponseDTO.map); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
|
|
||
| export class BaseResponseDTO { | ||
| id: number; | ||
| created_at: Date; | ||
| updated_at: Date; | ||
|
|
||
| constructor(data: { id: number; created_at: Date; updated_at: Date }) { | ||
| this.id = data.id; | ||
| this.created_at = data.created_at; | ||
| this.updated_at = data.updated_at; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| export class PaginatedResponseDTO<T> { | ||
| content: T[]; | ||
| total_elements: number; | ||
| total_pages: number; | ||
| size: number; | ||
| page: number; | ||
|
|
||
| constructor(data: { | ||
| content: T[]; | ||
| total_elements: number; | ||
| size: number; | ||
| page: number; | ||
| }) { | ||
| this.content = data.content; | ||
| this.total_elements = data.total_elements; | ||
| this.size = data.size > 0 ? data.size : 0; | ||
| this.total_pages = data.size > 0 ? Math.ceil(data.total_elements / data.size) : 0; | ||
| this.page = data.page; | ||
| } | ||
|
|
||
| static from<T>( | ||
| items: T[], | ||
| totalCount: number, | ||
| page: number, | ||
| limit: number | ||
| ): PaginatedResponseDTO<T> { | ||
| return new PaginatedResponseDTO({ | ||
| content: items, | ||
| total_elements: totalCount, | ||
| size: limit, | ||
| page | ||
| }); | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.