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

@yraylabs/api

v1.0.0

Published

Official TypeScript/JavaScript SDK for Yraylabs Storage and Email Services

Downloads

60

Readme

@yraylabs/api

Official TypeScript/JavaScript SDK for Yraylabs Storage and Email Services. This package provides a simple, type-safe interface to interact with the Yraylabs API.

Installation

npm install @yraylabs/api

Getting API Keys

To use the Yraylabs API services, you'll need API keys. To get started, please contact [email protected] to generate a user account and obtain your API keys.

You'll receive separate API keys for:

  • Storage Service - For file upload, download, and management operations
  • Email Service - For sending and managing emails

Quick Start

import YraylabsClient from '@yraylabs/api';

const client = new YraylabsClient({
  storageApiKey: 'your-storage-api-key',
  emailApiKey: 'your-email-api-key'
});

// Use storage service
const result = await client.storage?.upload(file, {
  bucket: 'documents',
  isPublic: true
});

// Use email service
const email = await client.email?.send({
  to: '[email protected]',
  subject: 'Welcome!',
  html: '<h1>Welcome!</h1>'
});

Features

  • TypeScript Support - Full type definitions included
  • Storage Service - Upload, download, list, and manage files
  • Email Service - Send emails with HTML/text support
  • Queue Service - Process and monitor job queues
  • Browser & Node.js - Works in both environments
  • Error Handling - Comprehensive error handling with typed errors

API Reference

Initialization

import YraylabsClient from '@yraylabs/api';

// Basic usage - provide the API keys you need
const client = new YraylabsClient({
  storageApiKey: 'your-storage-api-key', // Required for storage operations
  emailApiKey: 'your-email-api-key'      // Required for email operations
});

// You only need to provide the keys for services you'll use
const storageOnlyClient = new YraylabsClient({
  storageApiKey: 'your-storage-api-key'
});

const emailOnlyClient = new YraylabsClient({
  emailApiKey: 'your-email-api-key'
});

Note: Services (storage, email, queue) will be null if their corresponding API key is not provided. Use optional chaining (?.) when calling service methods, or check if the service exists before using it.

Storage Service

Upload File

const result = await client.storage?.upload(file, {
  bucket: 'documents',
  key: 'custom-path/file.pdf', // Optional
  isPublic: true, // Optional, default: false
  expiresAt: new Date('2026-12-31'), // Optional
  metadata: { category: 'invoice', year: 2026 } // Optional
});

console.log(result?.file.id);
console.log(result?.file.url);

List Files

const files = await client.storage?.listFiles('documents', 20);
console.log(files?.files);
console.log(files?.pagination);

Get File Info

const fileInfo = await client.storage?.getFileInfo('documents', 'file-key.pdf');
console.log(fileInfo?.file);

Download File

const blob = await client.storage?.download('documents', 'file-key.pdf');
// Use the blob (e.g., create object URL, save to disk, etc.)
if (blob) {
  const url = URL.createObjectURL(blob);
}

Delete File

await client.storage?.deleteFile('documents', 'file-key.pdf');

Generate Signed URL

const signed = await client.storage?.generateSignedUrl('documents', 'file-key.pdf', {
  expires_in: 1800 // 30 minutes, default: 3600 (1 hour)
});
console.log(signed?.signed_url);

Email Service

Send Email

const email = await client.email?.send({
  from: '[email protected]', // Optional
  to: '[email protected]', // or ['[email protected]', '[email protected]']
  subject: 'Welcome!',
  html: '<h1>Welcome!</h1><p>Thank you for joining.</p>',
  text: 'Welcome!\n\nThank you for joining.', // Optional
  cc: ['[email protected]'], // Optional
  bcc: ['[email protected]'], // Optional
  reply_to: ['[email protected]'], // Optional
  tags: ['welcome', 'onboarding'], // Optional
  metadata: { campaign_id: '12345' }, // Optional
  headers: { 'X-Custom-Header': 'value' } // Optional
});

console.log(email?.id);
console.log(email?.status);

List Emails

const emails = await client.email?.list({
  per_page: 20, // Optional, default: 50, max: 100
  status: 'sent', // Optional: 'pending' | 'sent' | 'failed'
  tag: 'newsletter' // Optional
});

console.log(emails?.data);
console.log(emails?.pagination);

Get Email

const email = await client.email?.getEmail('email_abc123def456...');
console.log(email?.status);
console.log(email?.html);

Queue Service

Process Queue

const result = await client.queue?.process();
console.log(`Processed ${result?.processed} jobs`);
console.log(`Remaining: ${result?.remaining}`);

Get Queue Status

const status = await client.queue?.getStatus();
console.log(`Pending: ${status?.stats.pending}`);
console.log(`Failed: ${status?.stats.failed}`);
console.log(`Worker running: ${status?.worker.running}`);

Examples

Browser Example

import YraylabsClient from '@yraylabs/api';

const client = new YraylabsClient({
  storageApiKey: process.env.YRAYLABS_STORAGE_API_KEY!,
  emailApiKey: process.env.YRAYLABS_EMAIL_API_KEY!
});

// Upload file from input
const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
if (fileInput.files && fileInput.files[0]) {
  const result = await client.storage?.upload(fileInput.files[0], {
    bucket: 'uploads',
    isPublic: true
  });
  console.log('File uploaded:', result?.file.url);
}

// Send email
await client.email?.send({
  to: '[email protected]',
  subject: 'File Uploaded',
  html: '<p>Your file has been uploaded successfully!</p>'
});

Node.js Example

import YraylabsClient from '@yraylabs/api';
import fs from 'fs';

const client = new YraylabsClient({
  storageApiKey: process.env.YRAYLABS_STORAGE_API_KEY!
});

// Upload file from disk
const fileBuffer = fs.readFileSync('invoice.pdf');
const result = await client.storage?.upload(fileBuffer, {
  bucket: 'documents',
  isPublic: false,
  metadata: { type: 'invoice' }
});

// Download file
if (result) {
  const blob = await client.storage?.download('documents', result.file.key);
  if (blob) {
    const buffer = Buffer.from(await blob.arrayBuffer());
    fs.writeFileSync('downloaded.pdf', buffer);
  }
}

Error Handling

All methods throw errors that you can catch:

try {
  const result = await client.storage?.upload(file, {
    bucket: 'documents'
  });
} catch (error) {
  if (error instanceof Error) {
    console.error('Upload failed:', error.message);
  }
}

Common error scenarios:

  • 401 Unauthorized - Invalid or missing API key
  • 404 Not Found - File or email not found
  • 409 Conflict - File with same key already exists
  • 422 Unprocessable Entity - Validation error

TypeScript Types

All types are exported for your convenience:

import type {
  FileInfo,
  UploadResponse,
  Email,
  SendEmailResponse,
  // ... and more
} from '@yraylabs/api';

API Keys

To get your API keys, please contact [email protected] to generate a user account.

You'll need different API keys for different services:

  • Storage Service - Requires a storage API key (storageApiKey)
  • Email Service - Requires an email API key (emailApiKey)
  • Queue Service - Accepts any valid API key (will use queueApiKey if provided, otherwise falls back to storageApiKey or emailApiKey)

You only need to provide the API keys for the services you'll use:

// Only using storage
const storageClient = new YraylabsClient({
  storageApiKey: process.env.STORAGE_API_KEY!
});

// Only using email
const emailClient = new YraylabsClient({
  emailApiKey: process.env.EMAIL_API_KEY!
});

// Using both services
const fullClient = new YraylabsClient({
  storageApiKey: process.env.STORAGE_API_KEY!,
  emailApiKey: process.env.EMAIL_API_KEY!
});

Requirements

  • Node.js 18+ or modern browser with fetch support
  • TypeScript 5.0+ (optional, but recommended)

License

MIT

Support

For issues, questions, or feature requests, please contact the Yraylabs development team.