Ir al contenido

TypeScript SDK

SDK de TypeScript para openUBL. Ofrece tipos, cliente fetch y schemas Zod generados automáticamente desde el esquema OpenAPI.

Ventana de terminal
npm install @openubl/sdk
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 generado
console.log(data.firmado); // false
console.log(data.validado_sunat); // true
console.log(data.valid); // true | null
console.log(data.errors); // [] | null
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>
}
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);

Si prefieres no usar el cliente, puedes llamar directamente a la API REST. Mira el ejemplo completo en la guía de TypeScript.

HelperEndpointBody schema
createInvoicePOST /api/v1/invoice/createzInvoiceCreateRequest
createCreditNotePOST /api/v1/credit-note/createzCreditNoteCreateRequest
createDebitNotePOST /api/v1/debit-note/createzDebitNoteCreateRequest
createVoidedDocumentsPOST /api/v1/voided-documents/createzVoidedDocumentsCreateRequest
createSummaryDocumentsPOST /api/v1/summary-documents/createzSummaryDocumentsCreateRequest
createPerceptionPOST /api/v1/perception/createzPerceptionCreateRequest
createRetentionPOST /api/v1/retention/createzRetentionCreateRequest
signXmlPOST /api/v1/signzSignXmlBody
getVersionGET /api/v1/version

Todos los endpoints /create devuelven:

{
xml: string;
firmado: boolean;
validado_sunat: boolean;
valid: boolean | null;
errors: { code: string; message: string }[] | null;
}
  • valid y errors son null cuando validar_sunat=false.
  • Si validar_sunat=true y hay errores, la API responde HTTP 422 con detail=errors.

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.

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);

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}`);
}
Ventana de terminal
cd sdk/typescript
npm install
npm run generate # regenera src/ desde openapi.json
npm run build # compila TypeScript
npm test # ejecuta la suite de tests

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.