SDK de JavaScript

SDK de JavaScript

El SDK oficial de JavaScript para CrowdHandler https://www.crowdhandler.com, destinado a la gestión de salas de espera y colas. Funciona tanto en entornos Node.js como en navegadores.

  • Fácil integración: añade gestión de colas a cualquier aplicación de JavaScript con una sola llamada a una función
  • Implementación flexible: funciona en servidores Node.js, navegadores, Lambda@Edge, Cloudflare Workers y otros entornos de ejecución en el borde
  • Opciones de rendimiento: elige entre la validación de la API en tiempo real o la validación de la firma local, según tus necesidades
  • Continuidad de la cola: mantiene la posición del usuario tras las actualizaciones de página y entre sesiones
  • Compatibilidad con TypeScript: definiciones de tipos completas para una mejor experiencia de desarrollo
  • Acceso a la API: gestiona salas de espera, supervisa colas y accede a los datos analíticos mediante programación

Instalación

npm install crowdhandler-sdk

de CDN

<!-- Load from unpkg -->
<script src="https://unpkg.com/crowdhandler-sdk/dist/crowdhandler.umd.min.js"></script>

<!-- Or specify a version -->
<script src="https://unpkg.com/crowdhandler-sdk@2.4.0/dist/crowdhandler.umd.min.js"></script>

de módulos#

El SDK está disponible en varios formatos:

  • Módulos ES - import { init } from 'crowdhandler-sdk'
  • CommonJS - const crowdhandler = require('crowdhandler-sdk')
  • UMD - Disponible en window.crowdhandler cuando se carga mediante una etiqueta `script`
  • Importación dinámica - await import('crowdhandler-sdk')

rápido#

Node.js / del

const crowdhandler = require('crowdhandler-sdk');
// or ES modules: import { init } from 'crowdhandler-sdk';

// Initialize SDK
const { client, gatekeeper } = crowdhandler.init({
  publicKey: 'YOUR_PUBLIC_KEY',
  // Optional: add privateKey for private API access
  privateKey: 'YOUR_PRIVATE_KEY',
  request: req,  // Express request object
  response: res  // Express response object
});

// Validate the request
const result = await gatekeeper.validateRequest();

// Check for errors first
if (result.error) {
  console.error(`Validation error: ${result.error.message}`);
  // 4xx errors: promoted = false (always block access)
  // 5xx errors: promoted depends on trustOnFail setting
}

// Handle the validation result
if (result.setCookie) {
  gatekeeper.setCookie(result.cookieValue, result.domain);
}

if (result.stripParams) {
  return gatekeeper.redirectToCleanUrl(result.targetURL);
}

if (!result.promoted) {
  return gatekeeper.redirectIfNotPromoted();
}

// User is promoted - continue with your application
// ... your protected content here ...

// Record performance (optional but recommended)
await gatekeeper.recordPerformance();

Navegador /

// Using script tag
const { client, gatekeeper } = window.crowdhandler.init({
  publicKey: 'YOUR_PUBLIC_KEY',
  options: {
    mode: 'clientside'
  }
});

// Or using ES Modules
import { init } from 'crowdhandler-sdk';
const { client, gatekeeper } = init({
  publicKey: 'YOUR_PUBLIC_KEY',
  options: {
    mode: 'clientside'
  }
});

// Validate the request
const result = await gatekeeper.validateRequest();

// Handle the validation result
if (result.setCookie) {
  gatekeeper.setCookie(result.cookieValue, result.domain);
}

if (result.stripParams) {
  // Redirect to clean URL
  window.location.href = result.targetURL;
  return;
}

if (!result.promoted) {
  // Redirect to waiting room
  gatekeeper.redirectIfNotPromoted();
  return;
}

// User is promoted - your application continues
console.log('User granted access');

// Record performance (optional but recommended)
await gatekeeper.recordPerformance();

Cloudflare

import { init } from 'crowdhandler-sdk';

export default {
  async fetch(request, env, ctx) {
    const { gatekeeper } = init({
      publicKey: env.CROWDHANDLER_PUBLIC_KEY,
      cloudflareWorkersRequest: request
    });

    const result = await gatekeeper.validateRequest();

    // Workers have no mutable response object — build the outgoing
    // Response yourself using values from the result.
    if (!result.promoted) {
      return new Response(null, {
        status: 302,
        headers: { Location: result.targetURL }
      });
    }

    const originResponse = await fetch(request);
    const response = new Response(originResponse.body, originResponse);

    if (result.setCookie) {
      response.headers.append(
        'set-cookie',
        `crowdhandler=${result.cookieValue}; path=/; Secure`
      );
    }

    ctx.waitUntil(gatekeeper.recordPerformance());
    return response;
  }
};

básicos#

gatekeeper.validateRequest(params?)

El método principal para validar las solicitudes en el sistema de colas de CrowdHandler. Este método determina si se debe conceder a un usuario acceso a tu recurso protegido o si se le debe enviar a una sala de espera.

// Basic usage
const result = await gatekeeper.validateRequest();

// With custom parameters
const result = await gatekeeper.validateRequest({
  custom: {
    code: 'ABC123',
    captcha: 'xK9mN2pQ5vL8wR3tY6uZ1aS4dF7gH0j'
  }
});

Parámetros:

  • parámetros (opcional) - Objeto que contiene parámetros personalizados
    • personalizado - Objeto con cualquier par clave-valor que se vaya a enviar a la API de CrowdHandler

Cómo funciona:

  1. Comprobación del token: en primer lugar, comprueba si existe un token de sesión de CrowdHandler en las cookies
  2. Validación de la API: envía el token (o genera uno nuevo) a la API de CrowdHandler, incluyendo cualquier parámetro personalizado
  3. Posición en la cola: determina si se da prioridad al usuario en función de la capacidad actual
  4. Respuesta: Proporciona instrucciones sobre cómo gestionar la solicitud.

Objeto de retorno:

{
  promoted: boolean,      // true = grant access, false = send to waiting room
  setCookie: boolean,     // true = update the user's session cookie
  cookieValue: string,    // The session token to store in the cookie
  stripParams: boolean,   // true = remove CrowdHandler URL parameters
  targetURL: string,      // Where to redirect (clean URL or waiting room)
  slug: string,           // The waiting room slug (when not promoted)
  responseID: string,     // Response ID for performance tracking (when promoted)
  deployment: string,     // Deployment identifier from the API
  token: string,          // The session token
  hash: string | null,    // Signature hash for validation (when available)
  requested: string,      // Timestamp when the request was made
  liteValidatorRedirect: boolean,  // true = redirect to lite validator
  liteValidatorUrl: string         // URL for lite validator redirect
}

Comportamiento específico de cada modo:

  • Modo completo (predeterminado): realiza una llamada a la API en cada solicitud para llevar a cabo una validación en tiempo real
  • Modo híbrido: valida las firmas de forma local para los usuarios con privilegios, lo que reduce el número de llamadas a la API
  • Modo del lado del cliente: la validación se realiza íntegramente en el navegador mediante cookies

Gestión de errores:

try {
  const result = await gatekeeper.validateRequest();
  // ... handle result ...
} catch (error) {
  console.error('Validation failed:', error.message);
  console.error('Status code:', error.statusCode);
  // Handle based on trustOnFail setting
}

### gatekeeper.setCookie(value, domain?)

Sets the CrowdHandler session cookie. Always call this when `result.setCookie` is true to maintain the user's queue position. The optional `domain` parameter (provided in `result.domain`) enables proper cookie scoping for wildcard domains.

```javascript
if (result.setCookie) {
  gatekeeper.setCookie(result.cookieValue, result.domain);
}

gatekeeper.redirectToCleanUrl(url)

Elimina los parámetros de seguimiento de CrowdHandler de las URL. Úsalo cuando result.stripParams Es importante mantener las URL limpias.

if (result.stripParams) {
  return gatekeeper.redirectToCleanUrl(result.targetURL);
}

gatekeeper.redirectIfNotPromoted()

Método práctico que gestiona todo el proceso de redireccionamiento para los usuarios no promocionados. Gestiona automáticamente las cookies y los redireccionamientos.

if (!result.promoted) {
  return gatekeeper.redirectIfNotPromoted();
}

gatekeeper.redirectIfPromoted()

Redirige a los usuarios promocionados desde una implementación de «sala de espera» de vuelta al sitio de destino con nuevos parámetros de CrowdHandler. Este método está pensado específicamente para su uso en implementaciones de «sala de espera».

// In waiting room implementation
if (result.promoted) {
  return gatekeeper.redirectIfPromoted();
}

Caso de uso: Al crear una sala de espera personalizada que se ejecute en tu infraestructura, este método se encarga de la redirección al recurso protegido con los parámetros adecuados de CrowdHandler.

gatekeeper.recordPerformance(options?)

Registra métricas de rendimiento para ayudar a CrowdHandler a optimizar el flujo y la capacidad de las colas.

// Simple usage (recommended)
await gatekeeper.recordPerformance();

// With custom options
await gatekeeper.recordPerformance({
  sample: 1,             // Record 100% of requests (default 0.2)
  statusCode: 200,       // HTTP status code (default 200)
  overrideElapsed: 1234, // Custom timing in ms
  timeout: 1500          // Per-call API timeout in ms (default 1500)
});

gatekeeper.overrideWaitingRoomUrl(url)

Sustituye la sala de espera predeterminada de CrowdHandler por tu URL personalizada.

// Redirect to your custom queue page
gatekeeper.overrideWaitingRoomUrl('https://mysite.com/custom-queue');

de inicialización#

const instance = crowdhandler.init({
  // Required
  publicKey: 'YOUR_PUBLIC_KEY',
  
  // Optional
  privateKey: 'YOUR_PRIVATE_KEY',  // Required for private API methods
  
  // Request context (choose one based on your environment)
  request: req,                       // Express/Node.js request
  response: res,                      // Express/Node.js response
  lambdaEdgeEvent: event,             // Lambda@Edge event
  cloudflareWorkersRequest: request,  // Cloudflare Workers Request
  // (none)                           // Browser environment (auto-detected)
  
  // Options
  options: {
    mode: 'full',         // 'full' (default), 'hybrid', 'clientside'
    apiUrl: 'https://api.crowdhandler.com',  // Custom API endpoint
    debug: false,         // Enable debug logging
    timeout: 5000,        // API timeout in milliseconds
    trustOnFail: true,    // Allow access if API fails
    fallbackSlug: '',     // Fallback room slug when trustOnFail is false
    cookieName: 'crowdhandler',  // Custom cookie name (default: 'crowdhandler')
    cookieMaxAgeSeconds: 86400,  // Optional. Persist the cookie via Max-Age (seconds).
                                 // Omit for a session cookie (default).
    forceCloudflareWorkers: true,  // Optional. Bypass navigator-based runtime inference
                                   // and treat the runtime as Cloudflare Workers. Only `true`
                                   // is accepted; omit for auto-detection.
    waitingRoom: false,   // Set to true if SDK is running in a waiting room context
    liteValidator: false, // Enable lite validator mode (default: false)
    roomsConfig: [{       // Array of room configurations for lite validator
      domain: string,     // e.g. 'https://example.com'
      slug: string,       // Room identifier
      urlPattern?: string,  // URL pattern to match
      patternType?: 'regex' | 'contains' | 'all',
      queueActivatesOn?: number,  // Unix timestamp
      timeout?: number    // Timeout in seconds
    }]
  }
});

de validación#

Modo completo (predeterminado)

La mejor opción para la mayoría de las integraciones del lado del servidor.

  • Ventajas: configuración sencilla, no requiere clave privada, todas las funciones
  • Inconvenientes: llamada a la API en cada solicitud (latencia de 20-100 ms)

híbrido#

Para aplicaciones en las que el rendimiento es fundamental.

  • Ventajas: latencia mínima (2-10 ms), menos llamadas a la API
  • Inconvenientes: Requiere una clave privada y necesita JavaScript del lado del cliente para las funciones auxiliares.
const instance = crowdhandler.init({
  publicKey: 'YOUR_PUBLIC_KEY',
  privateKey: 'YOUR_PRIVATE_KEY',  // Required for hybrid mode
  options: { mode: 'hybrid' }
});

del lado del cliente

Para aplicaciones de una sola página y sitios web estáticos.

  • Ventajas: Funciona sin servidor, fácil integración
  • Inconvenientes: solo funciona en el lado del cliente, requiere JavaScript

de la cookie personalizada#

Por defecto, CrowdHandler utiliza encargado de controlar a la multitud como nombre de la cookie. Puedes sustituirlo por un nombre personalizado:

const { gatekeeper } = crowdhandler.init({
  publicKey: 'YOUR_PUBLIC_KEY',
  options: {
    cookieName: 'my-custom-queue'  // Use custom cookie name
  }
});

Esto resulta útil cuando:

  • Ejecución de varias instancias de CrowdHandler en el mismo dominio
  • Cómo evitar conflictos con las cookies existentes
  • Cumplimiento de las convenciones de nomenclatura específicas

de las cookies#

Por defecto, la cookie de CrowdHandler es una cookie de sesión — el navegador la elimina cuando el usuario cierra completamente la sesión (nota: muchos navegadores restauran las cookies de sesión si está activada la opción «continuar donde lo dejaste»). Para casos de uso en salas de espera en los que se desee que la posición de un usuario en la cola se mantenga tras reiniciar el navegador, activa la persistencia con cookieMaxAgeSeconds:

const { gatekeeper } = crowdhandler.init({
  publicKey: 'YOUR_PUBLIC_KEY',
  options: {
    cookieMaxAgeSeconds: 86400  // Persist for 24 hours via Max-Age
  }
});

Notas:

  • El valor se escribe como la cookie Max-Age atributo (preferible a Caduca porque no se ve afectado por la desviación del reloj del cliente).
  • Esta opción se aplica a todas las llamadas «Set-Cookie» que emite el SDK, tanto mientras el usuario está en la cola como tras la promoción.
  • Omite la opción (o déjala sin definir) para mantener el comportamiento original de la cookie de sesión.

Forzar el de Cloudflare Workers#

El SDK deduce el entorno de ejecución de Cloudflare Workers a partir de navigator.userAgent. Si esa señal no es fiable en tu entorno (compilaciones personalizadas de «workerd», empaquetadores que eliminan variables globales, entornos de pruebas), puedes hacer que la decisión sea explícita:

const { gatekeeper } = crowdhandler.init({
  publicKey: env.CROWDHANDLER_PUBLIC_KEY,
  cloudflareWorkersRequest: request,
  options: {
    forceCloudflareWorkers: true
  }
});

Solo verdadero se acepta: omite la opción de recurrir a la detección automática. Con debug: true, el SDK registra qué señal motivó la decisión, por ejemplo: [CH] Entorno de ejecución de Cloudflare Workers: true (mediante anulación) vs (mediante inferencia del navegador). La anulación se restablece cada init() llamada para que nunca se pierda entre reinicializaciones.

API#

El SDK ofrece un cliente unificado tanto para las API públicas como para las privadas:

// List all waiting rooms
const rooms = await client.rooms().get();

// Get specific room
const room = await client.rooms().get('room_id');

// Create a new room (requires privateKey)
const newRoom = await client.rooms().post({
  name: 'Product Launch',
  domain: 'example.com'
});

// Update room settings
await client.rooms().put('room_id', {
  capacity: 1000
});

// Delete a room
await client.rooms().delete('room_id');

disponibles#

API pública (solo clave pública):

  • client.requests() - Validación de la solicitud
  • client.responses() - Seguimiento de las respuestas
  • client.rooms() - Información sobre la sala de espera

API privada (requiere una clave privada):

  • client.account() - Información de la cuenta
  • client.accountPlan() - Detalles del plan de la cuenta
  • client.codes() - Gestión de códigos de acceso
  • client.domains() - Configuración del dominio
  • client.domainIPs() - Direcciones IP de dominios
  • client.domainReports() - Análisis de dominios
  • client.domainRequests() - Registros de solicitudes de dominio
  • client.domainRooms() - Espacios para un dominio
  • client.domainURLs() - URL protegidas
  • client.groups() - Grupos de códigos de acceso
  • client.groupBatch() - Operaciones con códigos de lote
  • client.groupCodes() - Códigos de un grupo
  • client.ips() - Gestión de direcciones IP
  • client.reports() - Informes analíticos
  • client.rooms() - Gestión de la sala de espera
  • client.roomReports() - Análisis de habitaciones
  • client.roomSessions() - Sesiones presenciales
  • client.sessions() - Gestión de sesiones
  • client.templates() - Plantillas para salas de espera

Todos los métodos admiten operaciones REST estándar cuando procede:

  • .get() - Mostrar todos los recursos u obtener uno concreto por su ID
  • .post(data) - Crear un nuevo recurso
  • .put(id, data) - Actualizar un recurso existente
  • .patch(id, datos) - Actualización parcial
  • .delete(id) - Eliminar recurso

La documentación completa de la API, con ejemplos de solicitudes y respuestas, está disponible en tu panel de control de CrowdHandler, en Cuenta → API.

de errores#

Todos los errores del SDK son casos de CrowdHandlerError con una estructura coherente:

try {
  const rooms = await client.rooms().get();
} catch (error) {
  console.error(error.message);    // The actual API error message
  console.error(error.statusCode); // HTTP status code (e.g., 401, 404)
  console.error(error.suggestion); // Helpful guidance for resolution
  console.error(error.code);       // Error code for programmatic handling
}

en los errores de la API#

El SDK conserva los mensajes de error exactos de la API de CrowdHandler, lo que te permite gestionar situaciones de error específicas:

try {
  const result = await gatekeeper.validateRequest({
    custom: { code: 'user-code' }
  });
} catch (error) {
  // Check the specific error message from the API
  if (error.message.includes('Invalid priority code')) {
    // Handle invalid access code
  }
  
  // For advanced debugging, access the full API response
  const apiResponse = error.context?.apiResponse;
}

de error habituales#

  • INVALID_CONFIG - Configuración del SDK no válida
  • MISSING_PRIVATE_KEY - Se requiere una clave privada para esta operación
  • API_CONNECTION_FAILED - No se puede acceder a la API de CrowdHandler
  • API_RESPUESTA_INVÁLIDA - La API ha devuelto un error
  • RATE_LIMITED - Demasiadas solicitudes (incluidas las de «retry-after»)

de integración#

Consulta el directorio de ejemplos para ver ejemplos completos y funcionales, entre los que se incluyen:

  • Implementaciones de Express.js (protección total, solo API, API privada)
  • Manejadores de Lambda@Edge
  • Integración con React
  • Patrones de gestión de errores
  • Uso de TypeScript

Express.

const express = require('express');
const crowdhandler = require('crowdhandler-sdk');

const app = express();

// Middleware to protect routes
async function protectRoute(req, res, next) {
  try {
    const { gatekeeper } = crowdhandler.init({
      publicKey: process.env.CROWDHANDLER_PUBLIC_KEY,
      request: req,
      response: res
    });

    const result = await gatekeeper.validateRequest();
    
    // Check if there was an error during validation
    if (result.error) {
      console.error(`API Error ${result.error.statusCode}: ${result.error.message}`);
      // 4xx errors (e.g., invalid key, bad request): promoted = false (user blocked)
      // 5xx errors (e.g., server error): promoted based on trustOnFail setting
    }
    
    if (result.setCookie) {
      gatekeeper.setCookie(result.cookieValue, result.domain);
    }
    
    if (result.stripParams) {
      return gatekeeper.redirectToCleanUrl(result.targetURL);
    }
    
    if (!result.promoted) {
      return gatekeeper.redirectIfNotPromoted();
    }
    
    // User is promoted, continue
    res.locals.gatekeeper = gatekeeper;
    next();
  } catch (error) {
    // This catches unexpected errors (e.g., network issues, config errors)
    console.error('CrowdHandler SDK error:', error.message);
    // trustOnFail: true (default) = allow access on error
    // trustOnFail: false = block access on error
    next();
  }
}

// Protect specific routes
app.get('/limited-product', protectRoute, (req, res) => {
  res.send('This is a limited product page!');
  
  // Record performance after response
  if (res.locals.gatekeeper) {
    res.locals.gatekeeper.recordPerformance();
  }
});

const crowdhandler = require('crowdhandler-sdk');

exports.handler = async (event) => {
  const { gatekeeper } = crowdhandler.init({
    publicKey: process.env.CROWDHANDLER_PUBLIC_KEY,
    lambdaEdgeEvent: event
  });

  const result = await gatekeeper.validateRequest();
  
  if (!result.promoted) {
    // Redirect to waiting room
    return {
      status: '302',
      statusDescription: 'Found',
      headers: {
        location: [{
          key: 'Location',
          value: result.targetURL
        }]
      }
    };
  }
  
  // Continue with normal request processing
  return event.Records[0].cf.request;
};

Cloudflare

El SDK incluye compatibilidad nativa con el entorno de ejecución de Cloudflare Workers (workerd), sin necesidad de polyfills de Node. Pasa los Workers Solicitud objeto a través de cloudflareWorkersRequest y el SDK utiliza código nativo recoger internamente para todas las llamadas a la API.

import { init } from 'crowdhandler-sdk';

export default {
  async fetch(request, env, ctx) {
    const { gatekeeper } = init({
      publicKey: env.CROWDHANDLER_PUBLIC_KEY,
      cloudflareWorkersRequest: request
    });

    const result = await gatekeeper.validateRequest();

    if (result.error) {
      console.error(`API Error ${result.error.statusCode}: ${result.error.message}`);
    }

    // Strip CrowdHandler params from a freshly promoted URL
    if (result.stripParams) {
      return new Response(null, {
        status: 302,
        headers: {
          Location: decodeURIComponent(result.targetURL),
          'Set-Cookie': `crowdhandler=${result.cookieValue}; path=/; Secure`
        }
      });
    }

    // Send unpromoted users to the waiting room
    if (!result.promoted) {
      return new Response(null, {
        status: 302,
        headers: { Location: result.targetURL }
      });
    }

    // Promoted: fetch the origin and attach the session cookie if needed
    const originResponse = await fetch(request);
    const response = new Response(originResponse.body, originResponse);

    if (result.setCookie) {
      response.headers.append(
        'set-cookie',
        `crowdhandler=${result.cookieValue}; path=/; Secure`
      );
    }

    // Performance recording continues after the response is returned
    ctx.waitUntil(gatekeeper.recordPerformance());
    return response;
  }
};

Workers frente a Express/Lambda: ¿en qué se diferencian?

  • Los trabajadores no tienen un objeto de respuesta modificable. Crea el Respuesta tú mismo utilizando los valores de resultado (cookieValue, URL de destino, setCookie) en lugar de recurrir a métodos auxiliares que modifican la respuesta in situ.
  • Uso ctx.waitUntil() para recordPerformance() para que la llamada a la métrica no retrase la respuesta del usuario. En los Workers, el SDK espera internamente a que se complete la llamada a la API subyacente (por lo que, en realidad, se vacía dentro de ctx.waitUntil); el tiempo máximo de la solicitud de envío está limitado a 1500 ms por defecto — pasar { timeout: <ms> } para afinar.
  • Por defecto modo: 'completo' (como se ha indicado anteriormente) solo necesita la clave pública. Se admite el modo híbrido, pero requiere enviar tu clave privada como un secreto de Worker; hazlo solo si has evaluado las ventajas e inconvenientes.

React / Next.

import { useEffect, useState } from 'react';
import { init } from 'crowdhandler-sdk';

function ProtectedComponent() {
  const [isPromoted, setIsPromoted] = useState(null);
  
  useEffect(() => {
    const checkAccess = async () => {
      const { gatekeeper } = init({
        publicKey: 'YOUR_PUBLIC_KEY',
        options: { mode: 'clientside' }
      });
      
      const result = await gatekeeper.validateRequest();
      
      if (!result.promoted) {
        window.location.href = result.targetURL;
      } else {
        setIsPromoted(true);
      }
    };
    
    checkAccess();
  }, []);
  
  if (isPromoted === null) return <div>Checking access...</div>;
  if (!isPromoted) return <div>Redirecting to waiting room...</div>;
  
  return <div>Protected content here!</div>;
}

avanzadas#

Anular de la sala de espera n.

gatekeeper.overrideWaitingRoomUrl('https://custom-wait.example.com');

de exclusión personalizados#

// Don't check these paths
gatekeeper.setIgnoreUrls(/\.(css|js|png|jpg)$/);

de la solicitud de anulación#

gatekeeper.overrideHost('example.com');
gatekeeper.overridePath('/special-path');
gatekeeper.overrideIP('203.0.113.0');
gatekeeper.overrideLang('en-US');
gatekeeper.overrideUserAgent('Custom Bot 1.0');

de la actuación n.º

// Basic usage (records automatically)
await gatekeeper.recordPerformance();

// With options
await gatekeeper.recordPerformance({
  sample: 1.0,           // Record 100% of requests (default 0.2)
  statusCode: 200,       // HTTP status code
  overrideElapsed: 1234, // Custom timing in ms
  timeout: 1500          // Per-call API timeout in ms (default 1500, overrides global SDK timeout)
});

de errores de prueba#

Para probar tu gestión de errores sin realizar llamadas reales a la API, puedes simular errores:

const { gatekeeper } = init({
  publicKey: 'YOUR_PUBLIC_KEY',
  request: req,
  response: res,
  options: {
    testError: {
      statusCode: 500,  // Simulate a 500 error
      message: 'Simulated server error for testing'
    }
  }
});

// This will return immediately with a simulated error
const result = await gatekeeper.validateRequest();
// result.error will contain the test error
// result.promoted will be true (with default trustOnFail: true)

Esto resulta útil para:

  • Pruebas de la lógica de gestión de errores en la fase de desarrollo
  • Comprobación del comportamiento de reserva para distintos tipos de error
  • Pruebas de integración sin afectar a las métricas de producción

Nota: Los errores de prueba 4xx siempre establecerán destacado: false, mientras que los errores de prueba 5xx respetan tu trustOnFail configuración.

«Lite Validator»#

El modo «Lite Validator» permite actualizar el token sin necesidad de realizar llamadas a la API, ya que comprueba la configuración de la sala de forma local. Para activarlo:

  1. Conjunto liteValidator: true en las opciones
  2. Recupera y proporciona la configuración de tus habitaciones desde la API de CrowdHandler
// First, fetch your rooms configuration
const { client } = init({ publicKey: 'YOUR_PUBLIC_KEY' });
const roomsResponse = await client.rooms().get();

// Then initialize with lite validator enabled
const { gatekeeper } = init({
  publicKey: 'YOUR_PUBLIC_KEY',
  request: req,
  response: res,
  options: {
    liteValidator: true,              // Enable lite validator
    roomsConfig: roomsResponse.result // Pass the rooms array from API
  }
});

// Handle the lite validator redirect
const result = await gatekeeper.validateRequest();

if (result.liteValidatorRedirect) {
  // Redirect to refresh token/session
  return gatekeeper.redirect(result.liteValidatorUrl);
}

Cuando se activa Lite Validator:

  • La URL coincide con una sala de tu configuración
  • Falta el token o tiene más de 12 horas de antigüedad
  • Redirige a CrowdHandler para actualizar la sesión

El SDK incluye herramientas de pruebas muy completas:

de pruebas local#

# Inicia el servidor de pruebas con tus claves
npm run test:server -- --publicKey=TU_CLAVE --privateKey=TU_CLAVE_PRIVADA

# Con opciones personalizadas
npm run test:server -- --apiUrl=https://staging-api.crowdhandler.com --mode=hybrid

# Modo de desarrollo (reconstruye automáticamente el SDK)
npm run test:server:dev

de prueba del navegador n.

  1. Iniciar el servidor de pruebas
  2. Accede a http://localhost:3000/test/browser-test.html
  3. Pruebas interactivas con integración real de la API

de prueba n.

# Ejecutar pruebas automatizadas en el servidor de pruebas
npm run test:client

con TypeScript#

Compatibilidad total con TypeScript, con definiciones de tipos incluidas:

import { init, CrowdHandlerError, ErrorCodes } from 'crowdhandler-sdk';
import type { Mode, Room, Domain, ValidationResult } from 'crowdhandler-sdk';

// All types are properly inferred
const { client, gatekeeper } = init({
  publicKey: 'YOUR_KEY'
});

// TypeScript knows this returns Room[]
const rooms = await client.rooms().get();

// Error handling with types
try {
  await client.domains().get();
} catch (error) {
  if (error instanceof CrowdHandlerError) {
    if (error.code === ErrorCodes.MISSING_PRIVATE_KEY) {
      // Handle missing key
    }
  }
}

sobre la compilación

El SDK se distribuye en varios formatos:

  • CommonJS (dist/crowdhandler.cjs.js) - Para Node.js require()
  • Módulos ES (dist/crowdhandler.esm.js) - Para la música moderna importar
  • UMD (dist/crowdhandler.umd.js) - Para navegadores a través de <script>
  • UMD Minified (dist/crowdhandler.umd.min.js) - Versión de producción del navegador