PR-220602: Adding first commit.

This commit is contained in:
Alejandro Lembke Barrientos 2025-01-12 04:24:44 +00:00
commit 5eaec8627f
Signed by: aleleba
GPG Key ID: F48D7CDEB47942BD
20 changed files with 5599 additions and 0 deletions

2
.dockerignore Normal file
View File

@ -0,0 +1,2 @@
#Quitar ENV
.env

4
.env.example Normal file
View File

@ -0,0 +1,4 @@
# CDN URL for app
CDN_URL=
# Port of express server
PORT=

69
.github/workflows/main-workflow.yml vendored Normal file
View File

@ -0,0 +1,69 @@
# This file contains the main workflow for the create-react-ssr project. It defines the steps and actions to be taken when the workflow is triggered.
# Name of the workflow
name: Main Workflow
# Define the events that trigger the workflow
on:
push:
branches: [ master ]
pull_request:
branches: ['*']
# Define the jobs that run as part of the workflow
jobs:
# Job to run unit tests
unit-testing:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v4
- name: Use Node.js 16
uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm test
# Job to build the package
test-build-package:
if: github.ref != 'refs/heads/master'
needs: [ unit-testing]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm run build
# Job and deploy app to Docker Hub
build-and-deploy:
if: github.ref == 'refs/heads/master'
needs: [ unit-testing ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
push: true
tags: aleleba/run-app-from-cdn:latest

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
.env

23
Dockerfile Normal file
View File

@ -0,0 +1,23 @@
# Usa una imagen base de Node.js
FROM node:lts
# Establece el directorio de trabajo en /app
WORKDIR /app
# Copia el package.json y el package-lock.json
COPY package*.json ./
# Instala las dependencias
RUN npm ci
# Copia el resto de la aplicación
COPY . .
# Construye la aplicación
RUN npm run build
# Expone el puerto en el que la aplicación se ejecutará
EXPOSE 3000
# Define el comando para ejecutar la aplicación
CMD ["npm", "start"]

11
PRNameGenerator.ts Normal file
View File

@ -0,0 +1,11 @@
const PRName = function () {
let ID = '';
// let characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
const characters = '0123456789';
for ( let i = 0; i < 6; i++ ) {
ID += characters.charAt(Math.floor(Math.random() * 10));
}
return 'PR-'+ID;
};
console.log(PRName());

60
README.md Normal file
View File

@ -0,0 +1,60 @@
# README.md
# Run App From CDN
Esta es una aplicación sencilla construida con Express que sirve cualquier aplicación a través de un enlace CDN. Utiliza `dotenv` para leer la URL del enlace como variable de entorno.
## Requisitos
- Node.js
- npm
## Instalación
1. Clona el repositorio:
```
git clone <URL_DEL_REPOSITORIO>
```
2. Navega al directorio del proyecto:
```
cd simple-express-app
```
3. Instala las dependencias:
```
npm install
```
4. Crea un archivo `.env` en la raíz del proyecto y añade la URL del enlace CDN:
```
CDN_URL=<TU_URL_CDN>
```
## Ejecución
Para ejecutar la aplicación, utiliza el siguiente comando:
```
npm start
```
La aplicación estará disponible en `http://localhost:3000`.
## Estructura del Proyecto
- `src/app.ts`: Punto de entrada de la aplicación.
- `src/controllers/index.ts`: Controlador que maneja la lógica para servir la aplicación.
- `src/routes/index.ts`: Configuración de las rutas de la aplicación.
- `src/types/index.ts`: Definiciones de tipos personalizados.
- `.env`: Variables de entorno.
- `tsconfig.json`: Configuración de TypeScript.
- `package.json`: Configuración de npm.
## Contribuciones
Las contribuciones son bienvenidas. Si deseas contribuir, por favor abre un issue o envía un pull request.

24
__tests__/index.test.ts Normal file
View File

@ -0,0 +1,24 @@
import request from 'supertest';
import express from 'express';
import { setRoutes } from '../src/routes/index';
import dotenv from 'dotenv';
dotenv.config();
const app = express();
setRoutes(app);
describe('GET /', () => {
it('should redirect to CDN URL', async () => {
const response = await request(app).get('/');
expect(response.status).toBe(302);
expect(response.header.location).toBe(process.env.CDN_URL);
});
it('should return 500 if CDN URL is not configured', async () => {
process.env.CDN_URL = '';
const response = await request(app).get('/');
expect(response.status).toBe(500);
expect(response.text).toBe('CDN URL not configured');
});
});

17
dist/app.js vendored Normal file
View File

@ -0,0 +1,17 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const dotenv_1 = __importDefault(require("dotenv"));
const index_1 = require("./routes/index");
dotenv_1.default.config();
const app = (0, express_1.default)();
const PORT = process.env.PORT || 3000;
app.use(express_1.default.json());
app.use(express_1.default.urlencoded({ extended: true }));
(0, index_1.setRoutes)(app);
app.listen(PORT, () => {
console.log(`Servidor corriendo en http://localhost:${PORT}`);
});

26
dist/controllers/index.js vendored Normal file
View File

@ -0,0 +1,26 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getIndex = void 0;
const getIndex = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
try {
const cdnUrl = process.env.CDN_URL;
if (!cdnUrl) {
res.status(500).send('CDN URL not configured');
return;
}
res.redirect(cdnUrl);
}
catch (error) {
res.status(500).send('Internal Server Error');
}
});
exports.getIndex = getIndex;

9
dist/routes/index.js vendored Normal file
View File

@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setRoutes = setRoutes;
const index_1 = require("../controllers/index");
function setRoutes(app) {
app.get('/', (req, res) => {
(0, index_1.getIndex)(req, res);
});
}

2
dist/types/index.js vendored Normal file
View File

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

5
jest.config.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
};

5255
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

30
package.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "run-app-from-cdn",
"version": "1.0.0",
"description": "Una aplicación sencilla en Express que sirve una aplicación a través de un enlace CDN.",
"main": "src/app.ts",
"scripts": {
"start": "node dist/app.js",
"build": "tsc",
"dev": "ts-node src/app.ts",
"test": "jest",
"check-updates": "npx npm-check-updates -u && npm i"
},
"dependencies": {
"dotenv": "^16.4.7",
"express": "^4.21.2"
},
"devDependencies": {
"@types/express": "^5.0.0",
"@types/jest": "^29.5.14",
"@types/node": "^22.10.5",
"@types/supertest": "^6.0.2",
"jest": "^29.7.0",
"supertest": "^7.0.0",
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2",
"typescript": "^5.7.3"
},
"author": "Alejandro Lembke Barrientos",
"license": "MIT"
}

17
src/app.ts Normal file
View File

@ -0,0 +1,17 @@
import express from 'express';
import dotenv from 'dotenv';
import { setRoutes } from './routes/index';
dotenv.config();
const app = express();
const PORT = process.env.PORT || 3000;
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
setRoutes(app);
app.listen(PORT, () => {
console.log(`Servidor corriendo en http://localhost:${PORT}`);
});

14
src/controllers/index.ts Normal file
View File

@ -0,0 +1,14 @@
import { Request, Response } from 'express';
export const getIndex = async (req: Request, res: Response): Promise<void> => {
try {
const cdnUrl = process.env.CDN_URL;
if (!cdnUrl) {
res.status(500).send('CDN URL not configured');
return;
}
res.redirect(cdnUrl);
} catch (error) {
res.status(500).send('Internal Server Error');
}
};

8
src/routes/index.ts Normal file
View File

@ -0,0 +1,8 @@
import { Application, Request, Response } from 'express';
import { getIndex } from '../controllers/index';
export function setRoutes(app: Application) {
app.get('/', (req: Request, res: Response) => {
getIndex(req, res);
});
}

7
src/types/index.ts Normal file
View File

@ -0,0 +1,7 @@
export interface CustomRequest extends Express.Request {
// Puedes agregar propiedades personalizadas aquí
}
export interface CustomResponse extends Express.Response {
// Puedes agregar propiedades personalizadas aquí
}

14
tsconfig.json Normal file
View File

@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}