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

@supernal/sdk-api

v1.0.0

Published

Supernal API SDK - Lightweight client for Supernal API communications with authentication

Readme

@supernal/sdk-api

Lightweight API client for Supernal services with built-in authentication. Handles HTTP requests, error handling, and automatic token management.

🚀 Installation

npm install @supernal/sdk-api @supernal/sdk-auth

📋 Quick Start

Basic API Client

import { SupernalAPI, UserManagementAPI } from '@supernal/sdk-api';
import { SupernalAuth, TokenManager } from '@supernal/sdk-auth';

// Setup authentication
const auth = new SupernalAuth({
  authUrl: 'https://auth.supernal.ai',
  clientId: 'your-client-id',
  redirectUri: 'https://yourapp.com/callback',
});

const tokenManager = new TokenManager(auth);

// Create API client
const api = new SupernalAPI({
  baseUrl: 'https://api.supernal.ai/v1',
  auth,
  tokenManager,
});

Making API Calls

// GET request
const response = await api.get('/users/me');
console.log('User:', response.data);

// POST request
const newProject = await api.post('/projects', {
  name: 'My Project',
  description: 'A new project',
});

// PUT request with custom headers
const updated = await api.put('/projects/123', data, {
  headers: { 'X-Custom-Header': 'value' },
});

// DELETE request
await api.delete('/projects/123');

Specialized API Clients

// User Management API
const userAPI = new UserManagementAPI({ auth, tokenManager });

// Get user profile
const profile = await userAPI.getProfile();

// Update profile
await userAPI.updateProfile({ name: 'New Name' });

// Get organizations
const orgs = await userAPI.getOrganizations();

// Project operations
const projects = await userAPI.getProjects();
const project = await userAPI.createProject({
  name: 'New Project',
  type: 'web_app',
});

Chrome Extension API

import { ChromeExtensionAPI } from '@supernal/sdk-api';

const extensionAPI = new ChromeExtensionAPI({ auth, tokenManager });

// Extension-specific operations
const data = await extensionAPI.getExtensionData();
await extensionAPI.saveExtensionData({ settings: {...} });
const settings = await extensionAPI.syncSettings();

🔧 API Reference

SupernalAPI

Main API client with authentication.

class SupernalAPI {
  constructor(config: ApiConfig);

  // HTTP methods
  get<T>(endpoint: string, options?: RequestOptions): Promise<ApiResponse<T>>;
  post<T>(
    endpoint: string,
    data?: any,
    options?: RequestOptions
  ): Promise<ApiResponse<T>>;
  put<T>(
    endpoint: string,
    data?: any,
    options?: RequestOptions
  ): Promise<ApiResponse<T>>;
  patch<T>(
    endpoint: string,
    data?: any,
    options?: RequestOptions
  ): Promise<ApiResponse<T>>;
  delete<T>(
    endpoint: string,
    options?: RequestOptions
  ): Promise<ApiResponse<T>>;

  // Auth helpers
  getCurrentUser(): Promise<AuthUser>;
  isAuthenticated(): Promise<boolean>;
  logout(): Promise<void>;
}

UserManagementAPI

Specialized client for user management operations.

class UserManagementAPI extends SupernalAPI {
  // User operations
  getProfile(): Promise<AuthUser>;
  updateProfile(data: Partial<AuthUser>): Promise<AuthUser>;

  // Organization operations
  getOrganizations(): Promise<any[]>;
  getOrganization(id: string): Promise<any>;

  // Project operations
  getProjects(): Promise<any[]>;
  getProject(id: string): Promise<any>;
  createProject(data: any): Promise<any>;
  updateProject(id: string, data: any): Promise<any>;
  deleteProject(id: string): Promise<void>;
}

ApiUtils

Utility functions for common API patterns.

class ApiUtils {
  static createAuthenticatedClient(
    baseUrl: string,
    auth: SupernalAuth
  ): SupernalAPI;
  static handleApiError(error: any): ApiError;
  static async *paginate<T>(
    api: SupernalAPI,
    endpoint: string
  ): AsyncGenerator<T[]>;
}

🎯 Types

interface ApiConfig {
  baseUrl: string;
  auth?: SupernalAuth;
  tokenManager?: TokenManager;
  timeout?: number;
  retries?: number;
}

interface ApiResponse<T = any> {
  data: T;
  status: number;
  headers: Record<string, string>;
}

interface RequestOptions {
  headers?: Record<string, string>;
  timeout?: number;
  retries?: number;
  skipAuth?: boolean;
}

🚀 Advanced Features

Automatic Token Management

The API client automatically handles token refresh:

// Token is automatically refreshed if expired
const response = await api.get('/protected-endpoint');

Error Handling

try {
  const response = await api.get('/endpoint');
} catch (error) {
  const apiError = ApiUtils.handleApiError(error);
  console.error('API Error:', apiError.message);

  if (apiError.status === 401) {
    // Handle authentication error
  } else if (apiError.status === 403) {
    // Handle authorization error
  }
}

Retry Logic

Built-in exponential backoff retry:

// Automatically retries failed requests
const response = await api.get('/unreliable-endpoint', {
  retries: 5,
  timeout: 10000,
});

Pagination

// Paginate through large datasets
for await (const batch of ApiUtils.paginate(api, '/large-dataset')) {
  console.log('Batch:', batch);
}

Custom Headers

// Add custom headers to requests
const response = await api.post('/endpoint', data, {
  headers: {
    'X-Custom-Header': 'value',
    'X-Request-ID': 'unique-id',
  },
});

📚 Examples

React Component

import { useEffect, useState } from 'react';
import { UserManagementAPI } from '@supernal/sdk-api';
import { useSupernalAuth } from './useSupernalAuth'; // From sdk-auth examples

export function ProjectList() {
  const [projects, setProjects] = useState([]);
  const [loading, setLoading] = useState(true);
  const { auth, tokenManager } = useSupernalAuth();

  const userAPI = new UserManagementAPI({ auth, tokenManager });

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

  const loadProjects = async () => {
    try {
      const projectList = await userAPI.getProjects();
      setProjects(projectList);
    } catch (error) {
      console.error('Failed to load projects:', error);
    } finally {
      setLoading(false);
    }
  };

  const createProject = async (data) => {
    try {
      const newProject = await userAPI.createProject(data);
      setProjects([...projects, newProject]);
    } catch (error) {
      console.error('Failed to create project:', error);
    }
  };

  if (loading) return <div>Loading...</div>;

  return (
    <div>
      <h2>Projects</h2>
      {projects.map(project => (
        <div key={project.id}>{project.name}</div>
      ))}
    </div>
  );
}

Node.js Server

import express from 'express';
import { SupernalAPI, ApiUtils } from '@supernal/sdk-api';
import { SupernalAuth } from '@supernal/sdk-auth';

const app = express();

const auth = new SupernalAuth({
  authUrl: 'https://auth.supernal.ai',
  clientId: process.env.SUPERNAL_CLIENT_ID!,
  clientSecret: process.env.SUPERNAL_CLIENT_SECRET!,
  redirectUri: 'https://yourapp.com/callback',
});

const api = ApiUtils.createAuthenticatedClient(
  'https://api.supernal.ai/v1',
  auth
);

app.get('/api/user', async (req, res) => {
  try {
    const user = await api.getCurrentUser();
    res.json(user);
  } catch (error) {
    const apiError = ApiUtils.handleApiError(error);
    res.status(apiError.status || 500).json(apiError);
  }
});

Chrome Extension

// background.js
import { ChromeExtensionAPI } from '@supernal/sdk-api';
import { SupernalAuth, TokenManager } from '@supernal/sdk-auth';

const auth = new SupernalAuth({
  authUrl: 'https://auth.supernal.ai',
  clientId: 'extension-client-id',
  redirectUri: chrome.identity.getRedirectURL(),
});

const tokenManager = new TokenManager(auth, {
  // Use chrome.storage instead of localStorage
  setItem: (key, value) => chrome.storage.local.set({ [key]: value }),
  getItem: async (key) => {
    const result = await chrome.storage.local.get(key);
    return result[key];
  },
  removeItem: (key) => chrome.storage.local.remove(key),
});

const extensionAPI = new ChromeExtensionAPI({ auth, tokenManager });

// Sync data with server
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
  if (request.action === 'sync') {
    try {
      const data = await extensionAPI.getExtensionData();
      sendResponse({ success: true, data });
    } catch (error) {
      sendResponse({ success: false, error: error.message });
    }
  }
});

🔧 Configuration

Environment Variables

# API Configuration
SUPERNAL_API_BASE_URL=https://api.supernal.ai/v1
SUPERNAL_API_TIMEOUT=30000
SUPERNAL_API_RETRIES=3

# Authentication
SUPERNAL_AUTH_URL=https://auth.supernal.ai
SUPERNAL_CLIENT_ID=your-client-id
SUPERNAL_CLIENT_SECRET=your-client-secret

Custom Configuration

const api = new SupernalAPI({
  baseUrl: 'https://api.supernal.ai/v1',
  auth,
  tokenManager,
  timeout: 60000, // 60 seconds
  retries: 5, // 5 retry attempts
});

🐛 Troubleshooting

Common Issues

  1. Authentication Errors (401)

    // Check if token is valid
    const isAuth = await api.isAuthenticated();
    if (!isAuth) {
      // Redirect to login
    }
  2. Network Timeouts

    // Increase timeout for slow endpoints
    const response = await api.get('/slow-endpoint', {
      timeout: 120000, // 2 minutes
    });
  3. Rate Limiting (429)

    // Built-in retry handles rate limiting
    // Or implement custom backoff

Debug Mode

Enable debug logging:

// Add debug headers to requests
const response = await api.get('/endpoint', {
  headers: { 'X-Debug': 'true' },
});

📞 Support

  • Documentation: https://docs.supernal.ai/sdk/api
  • GitHub: https://github.com/supernal-ai/supernal-sdk
  • Discord: https://discord.gg/supernal-ai

Version: 1.0.0
License: MIT