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

roaming-studios-auth

v1.0.0

Published

Package compartido para funcionalidad de Firebase/Firestore (leads, usuarios, content access).

Downloads

5

Readme

roaming-studios-auth

Package compartido para funcionalidad de Firebase/Firestore (leads, usuarios, content access).

Instalación

El package se instala automáticamente como workspace dependency. Agregar en package.json de la app:

{
  "dependencies": {
    "roaming-studios-auth": "workspace:*"
  }
}

Configuración

El package usa Firebase Admin SDK en el servidor (bypass reglas de seguridad). Cada app debe configurar las credenciales del service account en .env.local.

Opción 1: Service Account Key como JSON string (Recomendado)

FIREBASE_SERVICE_ACCOUNT_KEY={"type":"service_account","project_id":"tu-project-id",...}

Opción 2: Ruta al archivo del Service Account

FIREBASE_SERVICE_ACCOUNT_PATH=/path/to/service-account-key.json

Opción 3: Variables individuales

FIREBASE_PROJECT_ID=tu_project_id
FIREBASE_CLIENT_EMAIL=firebase-adminsdk-xxxxx@tu-proyecto.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"

Opción 4: Application Default Credentials (ADC) - Para cuando no puedes generar service account keys

Si las políticas de tu organización bloquean la creación de service account keys, puedes usar ADC:

  1. Instala Google Cloud CLI (si no lo tienes):

    # macOS
    brew install google-cloud-sdk
  2. Autentica con tu cuenta:

    gcloud auth application-default login
  3. Configura solo el project ID en .env.local:

    FIREBASE_PROJECT_ID=prana-pulse-a67dd

El código detectará automáticamente las credenciales de ADC.

Cómo obtener las credenciales

Para Service Account Keys (Opciones 1-3):

  1. Ve a Firebase Console
  2. Selecciona tu proyecto
  3. Ve a Project SettingsService Accounts
  4. Haz clic en Generate New Private Key
  5. Descarga el archivo JSON
  6. Opción 1: Copia el contenido completo del JSON y pégalo como string en FIREBASE_SERVICE_ACCOUNT_KEY
  7. Opción 2: Guarda el archivo y usa su ruta en FIREBASE_SERVICE_ACCOUNT_PATH
  8. Opción 3: Extrae project_id, client_email y private_key del JSON

⚠️ Importante: Nunca commitees el archivo JSON del service account. Agrégalo a .gitignore.

Si no puedes generar keys (Opción 4 - ADC):

  • Usa gcloud auth application-default login (requiere tener acceso al proyecto en Google Cloud)
  • Solo necesitas configurar FIREBASE_PROJECT_ID

Uso

Firestore Server (Admin SDK)

import { getFirestoreServer } from 'roaming-studios-auth/firestoreServer';

// En API routes (server-side)
// Usa Firebase Admin SDK - bypass reglas de seguridad
const db = getFirestoreServer();

Users Service (Cliente-side)

import { 
  createUser, 
  getUser, 
  updateUser,
  updateUserSubscription,
  updateUserRole
} from 'roaming-studios-auth/users/usersService';
import type { CreateUserInput, BaseUser } from 'roaming-studios-auth/users/types';

// Crear usuario (ejecutar en CLIENTE)
const { user, userData } = await createUser({
  email: '[email protected]',
  name: 'Juan Pérez',
  password: 'password123',
  source: 'contact-form',
});

// Obtener usuario
const userData = await getUser(user.uid);

// Actualizar usuario
await updateUser(user.uid, {
  subscription: 'premium',
  role: 'user',
});

⚠️ IMPORTANTE: El servicio de usuarios debe ejecutarse en el CLIENTE (navegador), no en el servidor. Usa Firebase Client SDK que requiere autenticación.

Leads Service (Server-side con Admin SDK)

import { 
  createLead, 
  getLeads, 
  getLeadById, 
  updateLeadStatus 
} from 'roaming-studios-auth/leads/leadsService';
import type { Lead, CreateLeadInput } from 'roaming-studios-auth/leads/types';

// Crear lead (ejecutar en SERVIDOR - API routes)
const lead = await createLead({
  email: '[email protected]',
  name: 'Juan Pérez',
  source: 'contact-form',
});

// Obtener leads
const allLeads = await getLeads();
const newLeads = await getLeads({ status: 'new' });

// Actualizar estado
await updateLeadStatus(lead.id, 'contacted');

API Reference

getFirestoreServer()

Obtiene la instancia de Firestore para uso en servidor. Lee las env vars automáticamente.

createLead(input: CreateLeadInput)

Crea un nuevo lead. Si ya existe un lead con el mismo email, actualiza el existente.

getLeads(filters?: LeadFilters)

Obtiene leads con filtros opcionales. Ordenados por fecha (más recientes primero).

getLeadById(leadId: string)

Obtiene un lead específico por ID.

updateLead(leadId: string, input: UpdateLeadInput)

Actualiza un lead.

updateLeadStatus(leadId: string, status: LeadStatus)

Actualiza solo el estado de un lead.

Estructura de Datos en Firestore

Colección users

users/{uid}
{
  email: string (required)
  name: string (required)
  subscription: 'free' | 'basic' | 'premium' | 'enterprise'
  role: 'lead' | 'user' | 'admin'
  isActive: boolean
  emailVerified: boolean
  createdAt: timestamp
  updatedAt: timestamp
  lastLogin?: timestamp
  phone?: string
  avatar?: string
  source?: 'signup' | 'contact-form' | 'invitation' | 'migration' | 'other'
  metadata?: Record<string, any>
}

Nota: Cada proyecto puede extender BaseUser con campos específicos usando TypeScript.

Colección leads (Legacy - usar users con role: 'lead' en su lugar)

leads/{leadId}
{
  email: string (required, unique)
  name?: string
  phone?: string
  source: string (default: 'contact-form')
  metadata: Record<string, any>
  status: 'new' | 'contacted' | 'converted' | 'archived'
  createdAt: timestamp
  updatedAt: timestamp
  notes?: string
}

Notas

Usuarios (Recomendado)

  • Cliente-side: El servicio de usuarios usa Firebase Client SDK y debe ejecutarse en el navegador
  • Autenticación: Crea usuarios en Firebase Auth + Firestore automáticamente
  • Evolución: Los usuarios pueden evolucionar de role: 'lead' a role: 'user' cuando compran/se registran
  • Reglas de Firestore: Necesitas configurar reglas que permitan escritura cuando request.auth != null

Leads (Legacy)

  • Firebase Admin SDK: El servicio de leads usa Admin SDK en servidor, que bypass las reglas de seguridad
  • Seguridad: Las credenciales del service account deben estar solo en .env.local (nunca en git)
  • Colección automática: Las colecciones se crean automáticamente al crear el primer documento
  • Deduplicación: Los emails se normalizan a lowercase

Reglas de Firestore Recomendadas

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Usuarios: solo pueden leer/escribir su propio documento
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
    
    // Leads: solo lectura para usuarios autenticados (si usas leads legacy)
    match /leads/{leadId} {
      allow read: if request.auth != null;
      allow write: if false; // Solo Admin SDK puede escribir
    }
  }
}