TypeScript SDK
@openubl/sdk
Sección titulada «@openubl/sdk»SDK de TypeScript para openUBL. Ofrece tipos, cliente fetch y schemas Zod generados automáticamente desde el esquema OpenAPI.
Instalación
Sección titulada «Instalación»npm install @openubl/sdk1. Helper tipado (recomendado)
Sección titulada «1. Helper tipado (recomendado)»import { createInvoice, SDK_VERSION, checkApiVersion } from "@openubl/sdk";import { zInvoiceCreateRequest } from "@openubl/sdk/zod.gen";
const request = zInvoiceCreateRequest.parse({ documento: { serie: "F001", numero: 1, proveedor: { ruc: "20100066603", razonSocial: "Softgreen S.A.C." }, cliente: { nombre: "Carlos", numeroDocumentoIdentidad: "12121212121", tipoDocumentoIdentidad: "6" }, detalles: [{ descripcion: "Item", cantidad: 10, precio: 100 }], }, firmar: false, validar_sunat: true,});
const { data, error } = await createInvoice({ body: request });if (error) throw new Error(JSON.stringify(error));
console.log(data.xml); // XML UBL 2.1 generadoconsole.log(data.firmado); // falseconsole.log(data.validado_sunat); // trueconsole.log(data.valid); // true | nullconsole.log(data.errors); // [] | null2. Firma digital desde TypeScript
Sección titulada «2. Firma digital desde TypeScript»import { createInvoice } from "@openubl/sdk";
const { data, error } = await createInvoice({ body: { documento: { /* ... */ }, firmar: true, validar_sunat: true, credenciales: { cert_pem: "-----BEGIN CERTIFICATE-----\n...", key_pem: "-----BEGIN PRIVATE KEY-----\n...", }, },});
if (data) { console.log(data.firmado); // true console.log(data.xml); // contiene <ds:Signature>}3. Cliente genérico
Sección titulada «3. Cliente genérico»import { client } from "@openubl/sdk";import { zInvoiceCreateRequest } from "@openubl/sdk/zod.gen";
const request = zInvoiceCreateRequest.parse({ documento: { /* ... */ }, firmar: false, validar_sunat: true,});
const { data, error } = await client.post("/api/v1/invoice/create", { body: request });if (error) throw new Error(JSON.stringify(error));
console.log(data.xml);console.log(data.firmado, data.validado_sunat, data.valid, data.errors);4. fetch nativo
Sección titulada «4. fetch nativo»Si prefieres no usar el cliente, puedes llamar directamente a la API REST. Mira el ejemplo completo en la guía de TypeScript.
Helpers disponibles
Sección titulada «Helpers disponibles»| Helper | Endpoint | Body schema |
|---|---|---|
createInvoice | POST /api/v1/invoice/create | zInvoiceCreateRequest |
createCreditNote | POST /api/v1/credit-note/create | zCreditNoteCreateRequest |
createDebitNote | POST /api/v1/debit-note/create | zDebitNoteCreateRequest |
createVoidedDocuments | POST /api/v1/voided-documents/create | zVoidedDocumentsCreateRequest |
createSummaryDocuments | POST /api/v1/summary-documents/create | zSummaryDocumentsCreateRequest |
createPerception | POST /api/v1/perception/create | zPerceptionCreateRequest |
createRetention | POST /api/v1/retention/create | zRetentionCreateRequest |
signXml | POST /api/v1/sign | zSignXmlBody |
getVersion | GET /api/v1/version | — |
Respuesta CreateResponse
Sección titulada «Respuesta CreateResponse»Todos los endpoints /create devuelven:
{ xml: string; firmado: boolean; validado_sunat: boolean; valid: boolean | null; errors: { code: string; message: string }[] | null;}validyerrorssonnullcuandovalidar_sunat=false.- Si
validar_sunat=truey hay errores, la API responde HTTP 422 condetail=errors.
Validación runtime con Zod
Sección titulada «Validación runtime con Zod»Los schemas Zod viven en @openubl/sdk/zod.gen y se regeneran automáticamente desde openapi.json. Puedes usarlos para validar cualquier payload antes de enviarlo:
import { zInvoiceCreateRequest, zProveedor, zCliente, zDocumentoVentaDetalle,} from "@openubl/sdk/zod.gen";
const proveedor = zProveedor.parse({ ruc: "20100066603", razonSocial: "Softgreen S.A.C." });const cliente = zCliente.parse({ nombre: "Carlos", numeroDocumentoIdentidad: "12121212121", tipoDocumentoIdentidad: "6" });const detalle = zDocumentoVentaDetalle.parse({ descripcion: "Item", cantidad: 10, precio: 100 });const request = zInvoiceCreateRequest.parse({ documento: { serie: "F001", numero: 1, proveedor, cliente, detalles: [detalle] }, firmar: false, validar_sunat: true,});Los helpers también ejecutan validación automática en el body de la petición, así que pasar un objeto mal formado devolverá un error tipado.
Manejo de errores
Sección titulada «Manejo de errores»Todas las llamadas devuelven { data, error }. Comprueba siempre error antes de usar data:
const { data, error } = await createInvoice({ body: request });
if (error) { // Puede ser un z.ZodError o el error devuelto por la API throw new Error(JSON.stringify(error));}
console.log(data.xml);Validación de versión
Sección titulada «Validación de versión»Verifica que tu SDK y la API compartan la misma versión:
import { checkApiVersion } from "@openubl/sdk";
const result = await checkApiVersion("http://localhost:8000");if (!result.ok) { throw new Error(`Desfase de versión: SDK ${result.sdkVersion} vs API ${result.apiVersion}`);}Desarrollo
Sección titulada «Desarrollo»cd sdk/typescriptnpm installnpm run generate # regenera src/ desde openapi.jsonnpm run build # compila TypeScriptnpm test # ejecuta la suite de testsAlcance del SDK
Sección titulada «Alcance del SDK»El SDK es solo un cliente HTTP tipado. No empaqueta ZIP, no envía a SUNAT ni procesa CDR: esas responsabilidades quedan en el cliente operativo.