simcapture-sdk
SDK de SimCapture, la plataforma de grabación y evaluación de simulación clínica. Expone su API REST como un cliente TypeScript tipado.
Cada entidad tiene su propio namespace (sc.Course, sc.Reservation, …) que devuelve handles navegables, y sus builders validan antes de tocar la red.
Características
- Namespaces por entidad con lookup por id o por nombre:
named()matchea exacto e informa si no hay match (NotFoundError) o si hay varios (AmbiguousMatchError, con los ids para desambiguar) - Entidades navegables:
reserva.organization()hace el fetch bajo demanda, y.rawexpone el registro completo del API, incluso lo que el SDK no modela - Builders fluidos:
save()valida local y reporta todos los campos faltantes en un soloValidationError, en vez de un round-trip por error - Value objects:
TimeWindowpara ventanas de tiempo (overlap half-open, UTC explícito),Location,Attachment all()recorre las páginas por dentro y concatena; corta solo con página vacía, y si el servidor nunca la devuelve lanza en vez de entregar media lista- Autenticación con caché del token y reintento transparente ante
401; las llamadas concurrentes comparten un único/authen vuelo - Errores tipados bajo
SimCaptureError, con el estado real del upstream en vez de un400genérico - Arquitectura hexagonal: el dominio solo conoce puertos (
HttpClient,TokenStore), así que los tests corren sin red y podés inyectar tu propio transporte - Build dual ESM/CJS con tipos
.d.tsgenerados y publicación automatizada en npm mediante GitHub Actions
Tecnologías
TypeScript, Bun, axios, GitHub Actions.
Instalación
npm install simcapture-sdk
Ejemplo de Uso
import { SimCapture, TimeWindow, Location, Reservation, SimCaptureError } from "simcapture-sdk";
const sc = new SimCapture({
apiUrl: process.env.SIMCAPTURE_API!,
inventoryUrl: process.env.SIMCAPTURE_INVENTORY_API!,
credentials: {
username: process.env.SIMCAPTURE_USER!,
password: process.env.SIMCAPTURE_PASSWORD!,
clientSubdomain: process.env.SIMCAPTURE_SUBDOMAIN!,
},
});
const org = await sc.Organization.named("Facultad de Medicina");
const room = new Location({ name: "P3-H1" });
const date = new TimeWindow("2026-06-05").start().at("23:00").end().at("23:10");
const reserva = await new Reservation()
.titled("Reserva de prueba")
.inOrganization(org) // handle, UUID o nombre
.at(room)
.when(date)
.save();
await reserva.organization(); // navegación: fetch bajo demanda
reserva.date.durationMinutes();
try {
await sc.Reservation.get("bad-id");
} catch (error) {
if (error instanceof SimCaptureError) console.error(error.status, error.message);
}
Motivación
La integración bidireccional entre la plataforma del Centro Interdisciplinario de Simulación Avanzada y SimCapture necesitaba el mismo cliente en varios microservicios. Extraerlo a un paquete versionado eliminó la duplicación de la lógica de autenticación y dejó las respuestas del API tipadas en un solo lugar.