wundertec-core
Version:
Librería estándar de utilidades e integraciones AWS + helpers generales
275 lines (206 loc) • 6.03 kB
Markdown
**Librería estándar de utilidades e integraciones AWS + helpers generales en TypeScript**
---
- **AWS SDK v3**: S3, SES y SNS con funciones para operaciones comunes y URLs firmados.
- **Fechas y zonas horarias**: `moment-timezone` con zona por defecto CDMX y opción de cambiar.
- **Temporizadores**: `sleep` y `withTimeout` para control de flujos asíncronos.
- **Colecciones**: `chunk`, `flatten`, `uniq`, `groupBy`.
- **Reintentos**: `retry` con `exponentialBackoff` configurable.
- **HTTP**: `AxiosClient` con métodos `get`, `post`, `put`, `delete`.
- **Configuración**: `loadEnv`, `getConfig` para manejo de `.env` y variables.
- **Logging**: `Logger` con niveles `info`, `warn`, `error`, `debug`.
---
```bash
npm install wundertec-core
yarn add wundertec-core
```
---
Si usas un archivo `.env`, al inicio de tu aplicación (por ejemplo en `src/index.ts`):
```ts
import { loadEnv } from "wundertec-core";
loadEnv(); // carga variables desde .env
```
| Variable | Descripción |
| ----------------------- | ------------------------------------------------------ |
| `DEFAULT_TIMEZONE` | Zona horaria por defecto (e.g. `America/Mexico_City`). |
| `AWS_REGION` | Región AWS (p.ej. `us-east-1`). |
| `AWS_ACCESS_KEY_ID` | ID de acceso AWS (si no usas roles). |
| `AWS_SECRET_ACCESS_KEY` | Clave secreta AWS. |
| `SES_FROM_ADDRESS` | Direccion “From” por defecto para SES. |
| `DEBUG` | Activa logs `debug` (`"true"` o `"false"`). |
> Si faltan variables, la librería usará defaults o fallará con error claro.
---
## 📦 Uso detallado
Importa todo desde el entrypoint:
```ts
import {
/* AWS S3 */
uploadObject,
getObject,
deleteObject,
getSignedGetUrl,
getSignedPutUrl,
/* AWS SES */
sendEmail,
sendRawEmail,
/* AWS SNS */
sendSMS,
publishTopic,
/* Fechas */
now,
format,
diff,
add,
subtract,
/* Temporizadores */
sleep,
withTimeout,
/* Colecciones */
chunk,
flatten,
uniq,
groupBy,
/* Reintentos */
retry,
exponentialBackoff,
/* HTTP */
AxiosClient,
/* Configuración */
getConfig,
/* Logging */
Logger,
} from "wundertec-core";
```
```ts
// Subir archivo
await uploadObject("mi-bucket", "path/archivo.txt", Buffer.from("Hola"));
// Obtener contenido
const data: Buffer = await getObject("mi-bucket", "path/archivo.txt");
// Eliminar objeto
await deleteObject("mi-bucket", "path/archivo.txt");
// URL firmado GET
const urlGet = await getSignedGetUrl("mi-bucket", "path/privado.jpg", 600);
// URL firmado PUT
const urlPut = await getSignedPutUrl("mi-bucket", "path/subida.bin", 600);
```
```ts
// Enviar email HTML
await sendEmail(
["user@example.com"],
"Asunto de prueba",
"<h1>Hola</h1><p>Este es un email</p>"
);
// Envío raw (p.ej con attachments)
await sendRawEmail({ RawMessage: { Data: rawBuffer } });
```
```ts
// Enviar SMS directo
await sendSMS("+5215550000000", "Mensaje de prueba");
// Publicar en tópico SNS
await publishTopic(
"arn:aws:sns:us-east-1:123456789012:mi-topic",
"Notificación importante"
);
```
```ts
// Momento actual en CDMX
console.log(now().format());
// Formato específico y zona ET
console.log(format(new Date(), "YYYY-MM-DD HH:mm", "America/New_York"));
// Diferencia en días
console.log(diff("2025-05-01", "2025-04-24", "days"));
// Sumar 3 horas
const plus3 = add("2025-04-24T12:00:00Z", 3, "hours");
// Restar 30 minutos\console.log(subtract(plus3, 30, 'minutes').format());
```
```ts
// Pausar 2s
await sleep(2000);
// Timeout en promesa
await withTimeout(fetchData(), 5000, new Error("Tiempo excedido"));
```
```ts
// Chunk de 5 en 2
console.log(chunk([1, 2, 3, 4, 5], 2)); // [[1,2],[3,4],[5]]
// Aplanar
console.log(flatten([[1], [2, 3], []])); // [1,2,3]
// Únicos
console.log(uniq([1, 2, 2, 3, 3, 3])); // [1,2,3]
// Agrupar por clave
type Item = { type: string; value: number };
const items: Item[] = [
{ type: "A", value: 1 },
{ type: "B", value: 2 },
{ type: "A", value: 3 },
];
console.log(groupBy(items, (x) => x.type));
// => { A: [{...},{...}], B: [...] }
```
```ts
// Backoff exponencial
console.log(exponentialBackoff(0)); // 100
console.log(exponentialBackoff(1)); // 200
// Retry automático
const result = await retry(() => fetchUnstable(), {
retries: 5,
baseDelay: 200,
maxDelay: 5000,
});
```
```ts
const api = new AxiosClient({
baseURL: "https://api.miservicio.com",
timeout: 8000,
});
// GET JSON
const users = await api.get<User[]>("/users");
// POST datos y recibir respuest
const newUser = await api.post<User>("/users", { name: "Juan" });
// PUT y DELETE similares
await api.put("/items/1", { qty: 10 });
await api.delete("/items/2");
```
```ts
// Leer var con fallback
const port = getConfig("PORT", "3000");
console.log(`App corriendo en puerto ${port}`);
```
```ts
const log = new Logger("MiApp");
log.info("Inicio de aplicación");
log.warn("Esto es una advertencia");
log.error("Ha ocurrido un error");
log.debug("Valor X:", x); // solo si DEBUG=true
```
---
```bash
npm test
```
---
- Lint: `npm run lint`
- Build: `npm run build`
- Test: `npm test`
- Release: `npm run release` (publicación automática en NPM al mergear en `main`)
> Revisa [Jenkinsfile](./Jenkinsfile) para pipeline de ejemplo.
---
¡Bienvenidos PRs y issues! Sigue las guías de estilo y testing.
---
[](LICENSE) © Hypernetics