JSPM

  • Created
  • Published
  • Downloads 133
  • Score
    100M100P100Q103067F
  • License MIT

Browser-specific Lightweight JS SDK for Crudify GraphQL API with Refresh Token Pattern support

Package Exports

  • @nocios/crudify-browser

Readme

@nocios/crudify-browser

npm version License: MIT TypeScript Zero Dependencies

Core API SDK for the Crudify ecosystem - Lightweight JavaScript SDK for browser environments with zero dependencies.

SDK JavaScript ligero para acceder a la API GraphQL de Crudify desde navegadores. Incluye Refresh Token Pattern, operaciones CRUD completas y funcionalidades avanzadas de autenticación.

🚀 Características

  • 🔐 Autenticación Moderna: Sistema completo con Refresh Token Pattern
  • 🔄 Renovación Automática: Manejo transparente de tokens
  • 📊 CRUD Completo: Create, Read, Update, Delete con transacciones
  • 🌐 Multi-Ambiente: Configuración para dev, staging y production
  • 📱 TypeScript: Completamente tipado
  • ⚡ Lightweight: Sin dependencias externas
  • 🛡️ Seguro: Manejo seguro de tokens y autenticación

📖 Documentation

📦 Instalación

npm install @nocios/crudify-browser

Sin dependencias adicionales - completamente standalone.

🏗️ Configuración Rápida

import crudify from "@nocios/crudify-browser";

// 1. Configurar ambiente
crudify.config("dev"); // 'dev' | 'stg' | 'api' | 'prod'

// 2. Inicializar
await crudify.init("tu_public_api_key_aqui");

Variables de Entorno

const apiKey = process.env.REACT_APP_CRUDIFY_PUBLIC_API_KEY;
const environment = process.env.REACT_APP_CRUDIFY_ENV || "dev";

crudify.config(environment);
await crudify.init(apiKey);

🔐 Autenticación

Login

// Login con email o username
const result = await crudify.login("user@example.com", "password");

if (result.success) {
  console.log("Login exitoso:", result.data);
  // Token automáticamente almacenado
} else {
  console.error("Error:", result.errors);
}

// Verificar estado
const isLoggedIn = crudify.isLogin(); // true/false

Refresh Token Pattern

// Renovación manual
const refreshResult = await crudify.refreshAccessToken();

// Configurar tokens manualmente (restaurar sesión)
crudify.setTokens({
  accessToken: "stored_access_token",
  refreshToken: "stored_refresh_token",
  expiresAt: 1640995200000,
});

// Obtener información de tokens
const tokenData = crudify.getTokenData();
console.log("Tokens:", tokenData);

Logout

await crudify.logout(); // Limpia todos los tokens

📊 Operaciones CRUD

Create - Crear

// Crear con autenticación de usuario
const result = await crudify.createItem("products", {
  name: "Nuevo Producto",
  price: 99.99,
  category: "electronics",
});

// Crear público (solo con API key)
const publicResult = await crudify.createItemPublic("contacts", {
  name: "Juan Pérez",
  email: "juan@example.com",
});

Read - Leer

// Leer un item específico
const item = await crudify.readItem("products", {
  _id: "60f7b1234567890123456789",
});

// Leer múltiples con filtros y paginación
const items = await crudify.readItems("products", {
  filter: {
    category: "electronics",
    price: { $gte: 50, $lte: 200 },
  },
  pagination: {
    page: 1,
    limit: 20, // 20 items por página
  },
  sort: { createdAt: -1 },
});

if (items.success) {
  console.log("Productos:", items.data.items);
  console.log("Total:", items.data.total);
}

// ⚡ Obtener TODOS los resultados SIN paginación
const allItems = await crudify.readItems("products", {
  filter: { category: "electronics" },
  pagination: {
    limit: 0, // ✅ limit: 0 retorna TODOS los resultados
  },
  sort: { name: 1 },
});

// Leer con referencias pobladas (populate)
const orders = await crudify.readItems("orders", {
  filter: { status: "pending" },
  populate: [
    {
      path: "customerId", // Campo a poblar
      moduleKey: "customers", // Módulo referenciado
      select: ["name", "email"], // Campos a incluir
    },
    {
      path: "productId",
      moduleKey: "products",
      select: "name price stock", // También acepta string
    },
  ],
  pagination: { page: 1, limit: 10 },
});

Update - Actualizar

const result = await crudify.updateItem("products", {
  _id: "60f7b1234567890123456789",
  price: 89.99,
  discount: 10,
});

Delete - Eliminar

const result = await crudify.deleteItem("products", "60f7b1234567890123456789");

🔄 Transacciones

Ejecuta múltiples operaciones de forma atómica:

const transactionResult = await crudify.transaction({
  operations: [
    {
      operation: "create",
      moduleKey: "orders",
      data: { userId: "user123", total: 199.98 },
    },
    {
      operation: "update",
      moduleKey: "products",
      data: { _id: "product1", stock: { $inc: -2 } },
    },
  ],
});

if (transactionResult.success) {
  console.log("Transacción exitosa:", transactionResult.data);
}

🔧 Utilidades

Permisos y Estructura

// Obtener permisos del usuario
const permissions = await crudify.getPermissions();

// Obtener estructura del proyecto
const structure = await crudify.getStructure();

// Estructura pública (sin autenticación)
const publicStructure = await crudify.getStructurePublic();

Subida de Archivos

// Generar URL firmada
const signedUrl = await crudify.generateSignedUrl({
  fileName: "image.jpg",
  contentType: "image/jpeg",
});

if (signedUrl.success) {
  const { uploadUrl, fileUrl } = signedUrl.data;

  // Usar uploadUrl para subir archivo
  // Usar fileUrl como referencia pública
}

Interceptores de Respuesta

// Procesar todas las respuestas
crudify.setResponseInterceptor((response) => {
  console.log("Response:", response);

  // Transformar o agregar datos
  response.metadata = { timestamp: Date.now() };

  return response;
});

// Remover interceptor
crudify.setResponseInterceptor(null);

🚫 Cancelación de Requests

const controller = new AbortController();

// Cancelar después de 5 segundos
setTimeout(() => controller.abort(), 5000);

try {
  const result = await crudify.readItems(
    "products",
    {},
    {
      signal: controller.signal,
    }
  );
} catch (error) {
  if (error.name === "AbortError") {
    console.log("Request cancelado");
  }
}

📱 TypeScript

Tipos completos incluidos:

import crudify, { CrudifyResponse, CrudifyTokenData, CrudifyEnvType, NociosError } from "@nocios/crudify-browser";

const response: CrudifyResponse = await crudify.readItems("products", {});
const tokens: CrudifyTokenData = crudify.getTokenData();

// Manejo de errores tipado
if (!response.success && response.errorCode === NociosError.Unauthorized) {
  console.log("No autorizado");
}

🛠️ Ejemplo Práctico

import crudify from "@nocios/crudify-browser";

class ProductAPI {
  async init() {
    crudify.config(process.env.REACT_APP_CRUDIFY_ENV || "prod");
    await crudify.init(process.env.REACT_APP_CRUDIFY_PUBLIC_API_KEY);
  }

  async login(email, password) {
    return await crudify.login(email, password);
  }

  async getProducts(category = null, page = 1) {
    const filter = category ? { category } : {};

    return await crudify.readItems("products", {
      filter,
      pagination: {
        page,
        limit: 20,
      },
      sort: { name: 1 },
    });
  }

  async createProduct(productData) {
    return await crudify.createItem("products", productData);
  }

  async updateStock(productId, newStock) {
    return await crudify.updateItem("products", {
      _id: productId,
      stock: newStock,
    });
  }
}

// Uso
const api = new ProductAPI();
await api.init();

const loginResult = await api.login("user@example.com", "password");
if (loginResult.success) {
  const products = await api.getProducts("electronics");
  console.log("Productos:", products.data);
}

🔒 Características de Seguridad

  • ✅ Renovación automática de tokens (2 min antes de expirar)
  • ✅ Reintento automático en errores de autorización
  • ✅ Almacenamiento seguro de tokens
  • ✅ Configuración multi-ambiente
  • ✅ Manejo de errores estructurado

🔧 Configuración Avanzada

// Configuración con logging
await crudify.init("api_key", "debug"); // 'none' | 'debug'

// Verificar nivel de logging
console.log(crudify.getLogLevel());

// Limpiar recursos (Node.js)
await crudify.shutdown();

🚀 Renovación Automática

La librería maneja automáticamente:

  • Renovación preventiva: Renueva tokens 2 minutos antes de expirar
  • Recuperación de errores: Auto-renueva en errores 401 y reintenta operación
  • Verificación de estado: Métodos para verificar expiración de tokens

📚 Documentación Completa

Para ejemplos avanzados, configuración detallada y troubleshooting, consulta README_DEPTH.md.

📄 Licencia

MIT © Nocios


¿Necesitas ayuda? Consulta README_DEPTH.md para documentación completa.