Saltar al contenido

8 packages headless,
cada uno con responsabilidad clara

Importe solo lo que necesite. Cambie un adapter sin reescribir el resto. Cada package es una clase o conjunto de funciones puras con dependencias inyectadas.

Documentación técnica

  1. @kmee/shop-types

    Foundation

    Tipos compartidos (Product, ProductDetail, Cart, Brand, Category) y helpers puros. Contrato AuthProvider y Logger. Importado por todos los demás packages.

    Principales exports

    • Product
    • ProductDetail
    • Cart
    • AuthProvider
    • Logger
    • formatPrice
    • applyFilters
    @kmee/shop-types
    import { formatPrice, applyFilters } from "@kmee/shop-types"
    
    formatPrice({ value: 49.9 }, { locale: "pt-BR", currency: "BRL" })
    // -> "R$ 49,90"
    
    applyFilters(products, { categories: ["Films"] }, { min: 10, max: 100 })
  2. @kmee/shopinvader-client

    Backend client

    Cliente headless para Odoo vía Shopinvader. CartService, SalesService, AddressService, DeliveryCarriersService, LeadsService sobre OdooHttpClient con retry, timeout y auth inyectable.

    Principales exports

    • OdooHttpClient
    • CartService
    • SalesService
    • AddressService
    • DeliveryCarriersService
    • LeadsService
    @kmee/shopinvader-client
    import { OdooHttpClient, SalesService } from "@kmee/shopinvader-client"
    
    const sales = new SalesService(
      new OdooHttpClient({
        baseUrl,
        auth,
        getExtraHeaders: async () => ({ apikey: SUPABASE_ANON_KEY }),
      }),
    )
    
    const orders = await sales.list({ limit: 10 })
  3. @kmee/elasticsearch-shop

    Search & catalog

    Cliente Elasticsearch para listados, búsqueda y detalle de producto, categorías y brands. ProductService hace collapse por model.name, soporta filtro por tag, fallback de slug por wildcard, y Levenshtein para elegir mejor hit.

    Principales exports

    • ProductService
    • searchCategories
    • searchBrands
    @kmee/elasticsearch-shop
    import { ProductService } from "@kmee/elasticsearch-shop"
    
    const products = new ProductService(esConfig)
    
    await products.search({ searchTerm: "vinyl", page: 1, pageSize: 12 })
    await products.getByURLKey("oratape-mt80p")
    await products.getRelatedProducts([{ name: "ThermoFlex Plus" }])
  4. @kmee/supabase-auth-shop

    Auth adapter

    Adapter que implementa AuthProvider sobre @supabase/supabase-js. Enchúfelo en una OdooHttpClient y el token Supabase atraviesa hacia Odoo automáticamente.

    Principales exports

    • createSupabaseAuthProvider
    @kmee/supabase-auth-shop
    import { createSupabaseAuthProvider } from "@kmee/supabase-auth-shop"
    
    const auth = createSupabaseAuthProvider(supabase)
    // auth implementa AuthProvider - enchufe en OdooHttpClient.
    
    await auth.getToken()         // -> access_token o null
    await auth.isAuthenticated()  // -> false para anónimos por default
  5. @kmee/shop-storage

    Local persistence

    Persistencia local: CartStorage (UUID + datos del carrito con expiry) y CartItemsMetadataStorage (min_order_qty por item). Llaves de storage configurables.

    Principales exports

    • CartStorage
    • CartItemsMetadataStorage
    @kmee/shop-storage
    import { CartStorage } from "@kmee/shop-storage"
    
    const cartStorage = new CartStorage({
      cartKey: "myshop_cart",
      uuidKey: "myshop_cart_uuid",
      expiryDays: 60,
    })
    
    cartStorage.getOrCreateCartUuid()
    cartStorage.saveCartData({ uuid, items: [], lastUpdated: 0 })
  6. @kmee/admin-session

    Admin auth

    Sesión admin: JWT en cookie HttpOnly (jose), helpers de cookie para Next.js, getClientIp agnóstico de runtime, y AdminRateLimiter con store enchufable (MemoryRateLimitStore por default; cambie por Redis/KV en producción).

    Principales exports

    • signAdminSessionJwt
    • verifyAdminSessionToken
    • AdminRateLimiter
    • getClientIp
    @kmee/admin-session
    import {
      signAdminSessionJwt,
      AdminRateLimiter,
      getClientIp,
    } from "@kmee/admin-session"
    
    const limiter = new AdminRateLimiter()
    const ip = getClientIp(request.headers)
    const decision = await limiter.assertAllowed(ip)
    if (!decision.ok) return new Response("rate limited", { status: 429 })
    
    const token = await signAdminSessionJwt({ secret: SECRET })
  7. @kmee/shop-react

    React layer

    Providers y hooks React para conectar todo en la app: <CartProvider>, <WishlistProvider>, <SupabaseAuthProvider>, useProductsPage, useCategoriesPage, useBrandsAndCategories.

    Principales exports

    • CartProvider
    • WishlistProvider
    • SupabaseAuthProvider
    • useCart
    • useWishlist
    • useAuth
    • useProductsPage
    @kmee/shop-react
    import { useCart, useWishlist, useAuth } from "@kmee/shop-react"
    
    const { cart, addToCart, removeItem, loading } = useCart()
    const { items, add, isInWishlist } = useWishlist()
    const { user, signInWithPassword, signOut } = useAuth()
  8. @kmee/shop-ui

    UI components

    Componentes opinados (Tailwind + Radix): primitives (Button, Badge, Skeleton, Sheet, DropdownMenu, Select, Input, Tabs, Table) y ~20 componentes de dominio. Tema vía CSS vars + Tailwind preset compatible con shadcn.

    Principales exports

    • ProductCard
    • AddToCartButton
    • CartDrawer
    • ProductGallery
    • ProductFilters
    • HeroCarousel
    • GlobalHeader
    • Footer
    @kmee/shop-ui
    // tailwind.config.ts del cliente
    import shopUiPreset from "@kmee/shop-ui/tailwind-preset"
    
    export default {
      presets: [shopUiPreset],
      content: [
        "./app/**/*.{ts,tsx}",
        "./node_modules/@kmee/shop-ui/src/**/*.{ts,tsx}",
      ],
    }

¿Necesita un package customizado?

¿Tiene caso de uso que no cabe en las 8 libs? KMEE desarrolla adapters específicos (gateway de pago, ERP terceiro, marketplace).