npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@folyo/sdk

v0.1.1

Published

SDK oficial de Folyo para facturación electrónica chilena (DTE + SII). Del código al SII.

Readme

@folyo/sdk

SDK oficial de Folyo para facturación electrónica chilena (DTE + SII). Del código al SII. Sin escalas.

  • TypeScript nativo, tipos derivados del OpenAPI oficial de la API.
  • ESM + CJS, sin dependencias de runtime (usa el fetch global de Node 18+).
  • Manejo de errores tipado, reintentos con backoff y emisión asíncrona con polling.
  • Redacción automática de credenciales: el cliente y los errores nunca exponen tu API key, tu JWT ni material sensible (clave SII, .pfx, CAF, secretos).

Instalación

pnpm add @folyo/sdk
# o
npm install @folyo/sdk
# o
yarn add @folyo/sdk
# o
bun add @folyo/sdk

Requiere Node.js >= 18.

Quickstart: emitir una factura electrónica (DTE 33)

import { Folyo } from "@folyo/sdk";

const folyo = new Folyo({ apiKey: process.env.FOLYO_API_KEY! });

// Emisión asíncrona + espera del resultado por polling.
const job = await folyo.dte.emitirYEsperar(
  {
    tipo_dte: 33, // Factura Electrónica
    receptor: {
      rut: "12.345.678-9",
      razon_social: "Cliente SpA",
      giro: "Comercio",
      direccion: "Av. Siempre Viva 123",
      comuna: "Santiago",
    },
    detalle: [
      {
        nombre: "Servicio de consultoría",
        cantidad: 1,
        precio: 100000,
        monto: 100000, // requerido
      },
    ],
  },
  { idempotencyKey: crypto.randomUUID() },
);

console.log(job.estado); // "completed"
console.log(job.result?.track_id, job.folio);

Emisión cruda (solo encolar) + polling manual

const encolada = await folyo.dte.emitir(body, { idempotencyKey: crypto.randomUUID() });
console.log(encolada.job_id, encolada.folio);

// más tarde, o desde un webhook `dte.emitido`:
const job = await folyo.dte.getEmision(encolada.job_id!);

Autenticación

Dos esquemas, mutuamente excluyentes:

// API key (recomendado server-side; no expira; fija tenant y empresa).
const folyo = new Folyo({ apiKey: "tu-api-key" });

// JWT (sesión de usuario).
const folyo = new Folyo({ token: "access-token-jwt" });

El SDK envía la API key tal cual en el header X-API-Key (no asume prefijo). Con API key la empresa queda fijada por la key.

Configuración

const folyo = new Folyo({
  apiKey: process.env.FOLYO_API_KEY!,
  baseURL: "https://api.folyo.cl", // por defecto; usa http://localhost:8080 en local
  timeoutMs: 30000, // timeout por request
  maxRetries: 2, // reintentos ante 429 / 503 idempotentes
  userAgent: "mi-app/1.0", // sufijo opcional del User-Agent
  // fetch: customFetch,      // inyectable (tests, proxies)
});

Recursos disponibles

| Namespace | Métodos | |---|---| | folyo.dte | emitir, emitirYEsperar, getEmision, listDocumentos, downloadXml, downloadPdf, regeneratePdf, getEstado, getEstadoEnvio, getEmitidos, getRecibidos, getContribuyente, getSituacionTributaria | | folyo.folios | info, cargarCaf, solicitar | | folyo.rcv | periodos, get, sync, resumenIva | | folyo.clientes | list, upsert, importar, buscarPorRut, update, delete | | folyo.empresa | list, seleccionar | | folyo.acuse | registrar, pendientes, estado | | folyo.rcof | enviar, resumen | | folyo.webhooks | list, create, update, delete | | folyo.apiKeys | list, create, delete |

Algunos endpoints (clientes, RCV, plantillas, listado de documentos) requieren "panel operativo" y pueden devolver 403 en planes solo-API.

Idempotencia

Para dte.emitir / dte.emitirYEsperar, pasa una idempotencyKey (8-64 chars [a-zA-Z0-9_-], UUID v4 recomendado). Un reenvío con la misma key y el mismo cuerpo devuelve el mismo job_id sin quemar un folio nuevo. Además habilita el reintento seguro ante 503 del lado del SDK.

const key = crypto.randomUUID();
await folyo.dte.emitir(body, { idempotencyKey: key });
// reintento seguro con la misma key → mismo job_id
await folyo.dte.emitir(body, { idempotencyKey: key });

Una misma key con un cuerpo distinto produce 409 IDEMPOTENCY_KEY_CONFLICT (FolyoValidationError).

Manejo de errores

Todos los errores heredan de FolyoError y exponen status, code y requestId (nunca el cuerpo de la request).

import {
  FolyoError,
  FolyoAuthError, // 401
  FolyoRateLimitError, // 429 (.retryAfter en segundos)
  FolyoQuotaError, // 402 / 403 (PLAN_LIMIT, PAYMENT_REQUIRED, ...)
  FolyoValidationError, // 400 / 409 / 422
  FolyoConnectionError, // red / timeout
  FolyoSiiUnavailableError, // 502 / 503 / 504 (.retryAfter)
} from "@folyo/sdk";

try {
  await folyo.dte.emitir(body, { idempotencyKey: crypto.randomUUID() });
} catch (err) {
  if (err instanceof FolyoRateLimitError) {
    console.warn(`Rate limit; reintenta en ${err.retryAfter}s`);
  } else if (err instanceof FolyoQuotaError) {
    console.error(`Cuota/plan: ${err.code}`); // PLAN_LIMIT, PAYMENT_REQUIRED...
  } else if (err instanceof FolyoSiiUnavailableError) {
    console.error("El SII no está disponible, reintenta más tarde.");
  } else if (err instanceof FolyoError) {
    console.error(`${err.code ?? err.status}: ${err.message} (req ${err.requestId})`);
  }
}

Reintentos automáticos

El SDK reintenta con backoff exponencial (respetando Retry-After) ante 429 y 503 solo en operaciones idempotentes: cualquier GET, y POST /dte/emitir solo si entregaste una Idempotency-Key. Ajusta con maxRetries.

Seguridad

  • El cliente y todos los objetos de error redactan la credencial a *** al serializar (JSON.stringify) o al imprimirse (util.inspect).
  • Los errores nunca incluyen el cuerpo de la request (que puede traer la clave del SII o un .pfx).
  • Sin telemetría ni logging por defecto.

Licencia

MIT — Folyo Technologies SpA.