Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/config/swagger.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import swaggerJSDoc from 'swagger-jsdoc';

const PORT = process.env.PORT || 4000;

const swaggerDefinition = {
openapi: '3.0.0',
info: {
Expand All @@ -8,8 +10,8 @@ const swaggerDefinition = {
description: 'Documentación Obelisco API',
},
servers: [
{
url: 'http://localhost:3000', // Cambiar en producción
{
url: `http://localhost:${PORT}`, // Cambiar en producción
},
],
components: {
Expand Down Expand Up @@ -82,6 +84,12 @@ const swaggerDefinition = {
},
},
},
Component: {
type: 'object',
properties: {
html: { type: 'string' },
},
},
},
},
};
Expand Down
68 changes: 68 additions & 0 deletions src/controllers/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { fetchComponent } from '@services/component';
import { componentDTO } from '@utils/dtos';
import sendResponse from '@utils/sendResponse';
import { Request, Response, RequestHandler } from 'express';

/**
* @openapi
* /api/componentes/{name}:
* get:
* summary: Obtener un componente
* tags:
* - Component
* parameters:
* - in: path
* name: name
* required: true
* description: Nombre del componente a obtener (por ejemplo, "header" o "footer").
* schema:
* type: string
* - in: query
* name: encoded
* required: false
* description: Si es true, devuelve el base64 sin decodificar.
* schema:
* type: boolean
* - in: query
* name: html
* required: false
* description: Si es true, devuelve el base64 decodificado como HTML (text/html).
* schema:
* type: boolean
* responses:
* 200:
* description: Datos del componente obtenidos exitosamente
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Component'
* text/html:
* schema:
* type: string
* 500:
* description: Error del servidor al obtener el componente
*/
export const getComponent: RequestHandler = async (req: Request, res: Response) => {
try {
const { name } = req.params as { name: string };
const { encoded, html } = req.query as { encoded?: string, html?: string };
const response = await fetchComponent(name);
if (!response) {
sendResponse(res, 404, {
status: 'error',
message: `Componente "${name}" no encontrado`,
});
return;
}
const encodedBool = String(encoded).toLowerCase() === 'true';
const htmlBool = String(html).toLocaleLowerCase() === 'true';
const responseDTO = componentDTO(response, encodedBool, htmlBool);

sendResponse(res, 200, responseDTO, !htmlBool);
} catch (error) {
sendResponse(res, 500, {
status: 'error',
message: 'API Obelisco: Error al obtener componente.',
});
}
};
39 changes: 39 additions & 0 deletions src/models/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import sequelize from '@config/database';
import { Component as ComponentType, UUID } from '@utils/types';
import { DataTypes, Model, Optional } from 'sequelize';

// Phone model

export class Component extends Model<Optional<ComponentType, 'id'>> implements ComponentType {
public id!: UUID;
public name!: string;
public code!: string;

// timestamps!
public readonly createdAt!: Date;
public readonly updatedAt!: Date;
public readonly deletedAt!: Date;
}

Component.init(
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
},
name: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
code: {
type: DataTypes.TEXT,
allowNull: false,
unique: true,
},
},
{ sequelize, modelName: 'Component', tableName: 'components', paranoid: true }
);

export default Component;
8 changes: 8 additions & 0 deletions src/routes/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { getComponent } from '@controllers/component';
import express from 'express';

const router = express.Router();

router.get('/:name', getComponent);

export default router;
2 changes: 2 additions & 0 deletions src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
import { Router } from 'express';
import footerRoutes from './footer';
import headerRoutes from './header';
import componentRoutes from './component';
import sendResponse from '@utils/sendResponse';
const router = Router();

router.use('/footer', footerRoutes);
router.use('/header', headerRoutes);
router.use ('/componentes', componentRoutes);

router.get('/', (req, res) => {
sendResponse(res, 200, { message: 'API Obelisco' });
Expand Down
11 changes: 11 additions & 0 deletions src/services/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Component from '@models/component';

export const fetchComponent = async (name: string) => {
try {
const component = await Component.findOne({ where: { name } });
return component;
} catch (error) {
throw new Error('Error al obtener el componente.');
}
};

11 changes: 11 additions & 0 deletions src/utils/dtos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,14 @@ export const footerLegalesDTO = (footer: any) => {
images: footer.images.map((i: any) => ImageDTO(i)),
};
};

export const componentDTO = (component: any, encoded: boolean = false, html: boolean = false) => {
const content = (!encoded || html)
? Buffer.from(component.code, 'base64').toString('utf-8')
: component.code;

if (html) return content;
return {
html: content,
};
};
Loading