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 🙏

© 2025 – Pkg Stats / Ryan Hefner

tiendu-sdk

v0.1.4

Published

Tiendu SDK

Readme

🛍️ Tiendu SDK

SDK oficial de Tiendu para crear tiendas online personalizadas con toda la potencia del backend de Tiendu.

Enfocate en crear la mejor experiencia de compra para tus clientes mientras Tiendu se encarga de la gestión de productos, órdenes, sincronización con Meta Business, Google Merchant y mucho más.


📦 Instalación

npm install @tiendu/sdk

o con yarn:

yarn add @tiendu/sdk

🚀 Inicio Rápido

import { Tiendu } from "@tiendu/sdk";

const sdk = Tiendu({
  storeId: 123,
  baseUrl: "https://api.tiendu.uy",
});

// Listar productos
const products = await sdk.listProducts();

// Obtener un producto específico
const product = await sdk.getProduct(456);

// Agregar producto al carrito
await sdk.addProductVariantToCart(789, 2);

⚙️ Configuración

Tiendu(config)

Inicializa el SDK con la configuración de tu tienda.

Parámetros:

| Parámetro | Tipo | Requerido | Descripción | | --------- | -------------- | --------- | ------------------------------------------------ | | storeId | number | ✅ | ID de tu tienda en Tiendu | | baseUrl | string | ✅ | URL base de la API de Tiendu | | fetch | typeof fetch | ❌ | Implementación personalizada de fetch (opcional) |

Ejemplo:

const sdk = Tiendu({
  storeId: 123,
  baseUrl: "https://api.tiendu.uy",
  fetch: customFetch, // Opcional: útil para SSR o entornos sin fetch nativo
});

📚 API Reference

Productos

listProducts(options?)

Lista todos los productos de la tienda con opciones de filtrado.

Parámetros:

| Opción | Tipo | Descripción | | ------------ | ---------------- | --------------------------------- | | search | string \| null | Buscar productos por texto | | isFeatured | boolean | Filtrar solo productos destacados |

Retorna: Promise<ProductListing[]>

Ejemplo:

// Todos los productos
const allProducts = await sdk.listProducts();

// Productos destacados
const featured = await sdk.listProducts({ isFeatured: true });

// Buscar productos
const searchResults = await sdk.listProducts({ search: "remera" });

getProduct(productId)

Obtiene los detalles completos de un producto específico.

Parámetros:

| Parámetro | Tipo | Descripción | | ----------- | -------- | --------------- | | productId | number | ID del producto |

Retorna: Promise<Product>

Ejemplo:

const product = await sdk.getProduct(123);
console.log(product.title);
console.log(product.description);
console.log(product.variants);
console.log(product.reviews);

getRelatedProducts(productId)

Obtiene productos relacionados a un producto específico.

Parámetros:

| Parámetro | Tipo | Descripción | | ----------- | -------- | --------------- | | productId | number | ID del producto |

Retorna: Promise<ProductListing[]>

Ejemplo:

const related = await sdk.getRelatedProducts(123);

Categorías

listCategories()

Lista todas las categorías de la tienda.

Retorna: Promise<CategoryListing[]>

Ejemplo:

const categories = await sdk.listCategories();

getCategory(categoryId)

Obtiene los detalles completos de una categoría incluyendo sus productos.

Parámetros:

| Parámetro | Tipo | Descripción | | ------------ | -------- | ------------------ | | categoryId | number | ID de la categoría |

Retorna: Promise<Category>

Ejemplo:

const category = await sdk.getCategory(456);
console.log(category.name);
console.log(category.products); // Array de productos en esta categoría

Carrito de Compras

addProductVariantToCart(productVariantId, quantity)

Agrega una variante de producto al carrito del usuario y abre el checkout embebido.

Parámetros:

| Parámetro | Tipo | Descripción | | ------------------ | -------- | ------------------------------ | | productVariantId | number | ID de la variante del producto | | quantity | number | Cantidad a agregar |

Retorna: Promise<{ updatedCartItemsQuantity: number }>

Ejemplo:

const result = await sdk.addProductVariantToCart(789, 2);
console.log(`Ahora hay ${result.updatedCartItemsQuantity} items en el carrito`);

getCartItemsQuantity()

Obtiene la cantidad total de items en el carrito del usuario.

Retorna: Promise<{ quantity: number }>

Ejemplo:

const { quantity } = await sdk.getCartItemsQuantity();
console.log(`El carrito tiene ${quantity} items`);

openCart()

Abre el checkout embebido de Tiendu en un iframe.

Retorna: Promise<HTMLIFrameElement>

Ejemplo:

await sdk.openCart();

Páginas

listPages()

Lista todas las páginas de la tienda.

Retorna: Promise<PageListing[]>

Ejemplo:

const pages = await sdk.listPages();

getPage(pageId)

Obtiene el contenido completo de una página.

Parámetros:

| Parámetro | Tipo | Descripción | | --------- | -------- | --------------- | | pageId | number | ID de la página |

Retorna: Promise<Page>

Ejemplo:

const page = await sdk.getPage(123);
console.log(page.title);
page.content.forEach((block) => {
  if (block.type === "heading") {
    console.log(`H${block.level}: ${block.text}`);
  } else if (block.type === "paragraph") {
    console.log(block.text);
  }
});

Blog

listBlogPosts()

Lista todos los posts del blog.

Retorna: Promise<BlogPost[]>

Ejemplo:

const posts = await sdk.listBlogPosts();

getBlogPost(blogPostId)

Obtiene el contenido completo de un post del blog.

Parámetros:

| Parámetro | Tipo | Descripción | | ------------ | -------- | ----------- | | blogPostId | number | ID del post |

Retorna: Promise<BlogPost>

Ejemplo:

const post = await sdk.getBlogPost(456);
console.log(post.title);
console.log(post.excerpt);
console.log(post.manager.name);
console.log(post.createdAt);

Gestión de Sesión

getShopperSessionToken()

Obtiene el token de sesión del usuario desde localStorage.

Retorna: Promise<string | null>

setShopperSessionToken(token)

Guarda el token de sesión del usuario.

Parámetros:

| Parámetro | Tipo | Descripción | | --------- | -------- | --------------- | | token | string | Token de sesión |

deleteShopperSessionToken()

Elimina el token de sesión del usuario.


🎨 Tipos TypeScript

El SDK incluye tipos completos para TypeScript. Los principales son:

Product

interface Product {
  id: number;
  title: string;
  description: string | null;
  basePriceInCents: number;
  averageRating: number; // 1 a 5
  reviewsQuantity: number;
  salesQuantity: number;
  isFeatured: boolean;
  isPhysical: boolean;
  images: Image[];
  attributes: ProductAttribute[];
  variants: ProductVariant[];
  specifications: ProductSpecification[] | null;
  reviews: ProductReview[];
}

ProductVariant

interface ProductVariant {
  id: number;
  priceInCents: number | null;
  weightInGrams: number | null;
  compareAtPriceInCents: number | null;
  stock: number | null;
  sku: string | null;
  coverImage: Image | null;
  attributes: ProductAttribute[]; // Cada atributo tiene un solo valor
}

ProductAttribute

interface ProductAttribute {
  id: number;
  name: string; // Ej: "Color", "Talle"
  values: ProductAttributeValue[]; // Ej: [{ id: 1, value: "Rojo" }]
}

Category

interface Category {
  id: number;
  name: string;
  isFeatured: boolean;
  description: string | null;
  coverImage: Image | null;
  products: ProductListing[];
}

Image

interface Image {
  id: number;
  url: string;
  alt: string;
  hasTransparency: boolean;
  height: number;
  width: number;
}

ProductReview

interface ProductReview {
  id: number;
  authorName: string;
  rating: number; // 1 a 5
  isVerifiedPurchase: boolean;
  content: string;
  createdAt: string;
}

Page y BlogPost

Ambos utilizan bloques de contenido estructurados:

type ContentBlock = ContentParagraphBlock | ContentHeadingBlock;

interface ContentParagraphBlock {
  id: number;
  type: "paragraph";
  text: string;
}

interface ContentHeadingBlock {
  id: number;
  type: "heading";
  level: 1 | 2 | 3;
  text: string;
}

💡 Ejemplos Completos

Crear una página de producto

import { Tiendu } from "@tiendu/sdk";

const sdk = Tiendu({
  storeId: 123,
  baseUrl: "https://api.tiendu.uy",
});

async function ProductPage({ productId }: { productId: number }) {
  const product = await sdk.getProduct(productId);
  const relatedProducts = await sdk.getRelatedProducts(productId);

  return (
    <div>
      <h1>{product.title}</h1>
      <img src={product.images[0]?.url} alt={product.images[0]?.alt} />
      <p>{product.description}</p>
      <p>Precio: ${product.basePriceInCents / 100}</p>

      {/* Variantes */}
      {product.variants.map((variant) => (
        <button
          key={variant.id}
          onClick={() => sdk.addProductVariantToCart(variant.id, 1)}
        >
          Agregar al carrito - ${variant.priceInCents! / 100}
        </button>
      ))}

      {/* Reviews */}
      <div>
        <h2>Opiniones ({product.reviewsQuantity})</h2>
        <p>★ {product.averageRating.toFixed(1)}</p>
        {product.reviews.map((review) => (
          <div key={review.id}>
            <p>
              <strong>{review.authorName}</strong>{" "}
              {review.isVerifiedPurchase && "✓ Compra verificada"}
            </p>
            <p>★ {review.rating}</p>
            <p>{review.content}</p>
          </div>
        ))}
      </div>

      {/* Productos relacionados */}
      <div>
        <h2>También te puede interesar</h2>
        {relatedProducts.map((related) => (
          <div key={related.id}>
            <img src={related.coverImage?.url} alt={related.title} />
            <p>{related.title}</p>
            <p>${related.basePriceInCents / 100}</p>
          </div>
        ))}
      </div>
    </div>
  );
}

Crear un catálogo con búsqueda

import { useState } from "react";
import { Tiendu } from "@tiendu/sdk";

const sdk = Tiendu({
  storeId: 123,
  baseUrl: "https://api.tiendu.uy",
});

function Catalog() {
  const [search, setSearch] = useState("");
  const [products, setProducts] = useState([]);

  const handleSearch = async (searchTerm: string) => {
    setSearch(searchTerm);
    const results = await sdk.listProducts({
      search: searchTerm || null,
    });
    setProducts(results);
  };

  return (
    <div>
      <input
        type="text"
        placeholder="Buscar productos..."
        value={search}
        onChange={(e) => handleSearch(e.target.value)}
      />

      <div className="products-grid">
        {products.map((product) => (
          <div key={product.id}>
            <img src={product.coverImage?.url} alt={product.title} />
            <h3>{product.title}</h3>
            <p>${product.basePriceInCents / 100}</p>
            <p>
              ★ {product.averageRating} ({product.reviewsQuantity})
            </p>
            {product.isFeatured && <span>⭐ Destacado</span>}
          </div>
        ))}
      </div>
    </div>
  );
}

Mostrar indicador de carrito

import { useEffect, useState } from "react";
import { Tiendu } from "@tiendu/sdk";

const sdk = Tiendu({
  storeId: 123,
  baseUrl: "https://api.tiendu.uy",
});

function CartIndicator() {
  const [quantity, setQuantity] = useState(0);

  useEffect(() => {
    loadCartQuantity();
  }, []);

  const loadCartQuantity = async () => {
    const { quantity } = await sdk.getCartItemsQuantity();
    setQuantity(quantity);
  };

  return (
    <button onClick={() => sdk.openCart()}>
      🛒 Carrito {quantity > 0 && `(${quantity})`}
    </button>
  );
}

🌐 Recursos

  • Crear cuenta: tiendu.uy
  • Panel de administración: Gestiona productos, órdenes y configuración
  • Soporte: Contacta al equipo de Tiendu para asistencia

📝 Notas Importantes

  • Precios: Todos los precios están en centavos (priceInCents). Dividí por 100 para mostrar el precio en tu moneda.
  • Sesión del Usuario: El SDK maneja automáticamente el token de sesión del usuario usando localStorage.
  • Checkout Embebido: Al agregar productos al carrito, se abre automáticamente el checkout de Tiendu en un iframe.
  • TypeScript: El SDK está completamente tipado. Importá los tipos desde @tiendu/sdk.

📄 Licencia

Consulta con Tiendu sobre los términos de uso del SDK.


¿Listo para crear tu tienda online? Visitá tiendu.uy y empezá hoy. 🚀