TypeScript SDK

Beta
⚠️

Work in Progress

This SDK is currently in beta and under active development. It is not recommended for production use as APIs and functionality may change without notice.

Current Status:

  • Designed for server-side use (Node.js primarily, with potential support for Deno, Bun, and Cloudflare Workers)
  • Core functionality is implemented but may have breaking changes
  • API responses and error handling are being standardized
  • Documentation and examples are being expanded

For the latest updates and changes, please check the GitHub repository.

Installation

Install the SDK using your preferred package manager:

npm
bash
npm install @fynlink/sdk
yarn
bash
yarn add @fynlink/sdk
pnpm
bash
pnpm add @fynlink/sdk

Dependencies

The SDK has the following dependencies that will be installed automatically:

  • axios - HTTP client for making API requests
  • bad-words - Content filtering and moderation
  • libsodium-wrappers-sumo - Cryptographic operations
  • nanoid - ID generation

Note: All modern package managers (npm, yarn, and pnpm) will handle these dependencies automatically. You don't need to install them separately.

Quick Start

Get started with the Fynlink SDK by following these examples:

Initialize Client

⚠️ Security Warning

This SDK is designed for server-side use only. Never expose your token or secret in client-side code or public repositories. Always store these credentials in secure environment variables on your server.

Quick Start
typescript
// Load credentials from environment variables
const token = process.env.FYNLINK_TOKEN;
const secret = process.env.FYNLINK_SECRET;

import { Fyn } from '@fynlink/sdk';

const fyn = new Fyn({
  token,    // Format: token_<your-token>
  secret    // Format: secret_<your-secret>, required only for view/list/update operations
});
Advanced Configuration
typescript
import { Fyn } from '@fynlink/sdk';

// Initialize with all available options
const fyn = new Fyn({
  // Required options
  token: 'token_<your-token>',
  secret: 'secret_<your-secret>', // Required only to view/list or update links

  // Optional configuration
  baseUrl: 'https://api.fyn.link/v1',  // Custom API endpoint
  timeout: 10000,                      // Request timeout in milliseconds
  
  // Cache configuration
  cache: {
    enabled: true,                     // Enable/disable caching
    maxSize: 1000,                     // Maximum number of items to cache
    ttl: '1h',                         // Time to live for cached items
    staleWhileRevalidate: true,        // Use stale cache while fetching fresh data
  },

  // Retry configuration
  retry: {
    maxRetries: 3,                     // Maximum number of retry attempts
    initialDelay: 1000,                // Initial delay between retries (ms)
    maxDelay: 5000,                    // Maximum delay between retries (ms)
    backoffFactor: 2,                  // Exponential backoff factor
  },

  // Debug configuration
  debug: {
    enabled: false,                    // Enable debug logging
    level: 'info',                     // Log level: 'debug' | 'info' | 'warn' | 'error'
    handler: console.log,              // Custom debug log handler
  }
});

Configuration Reference

Required Options
token

Your API token from the Fynlink Dashboard. Format: token_*

secret

Your API secret. Required only for viewing, listing, or updating links. Format: secret_*

Optional Options
baseUrl

Custom API endpoint. Default: https://api.fyn.link/v1

timeout

Request timeout in milliseconds. Default: 10000

Cache Options
cache.enabled

Enable or disable caching. Default: true

cache.maxSize

Maximum number of items to cache. Default: 1000

cache.ttl

Time to live for cached items. Default: '1h'

cache.staleWhileRevalidate

Use stale cache while fetching fresh data. Default: true

Retry Options
retry.maxRetries

Maximum number of retry attempts. Default: 3

retry.initialDelay

Initial delay between retries in milliseconds. Default: 1000

retry.maxDelay

Maximum delay between retries in milliseconds. Default: 5000

retry.backoffFactor

Exponential backoff factor. Default: 2

Debug Options
debug.enabled

Enable debug logging. Default: false

debug.level

Log level. Default: 'info'

debug.handler

Custom debug log handler. Default: console.log

Domains

Team

Analytics

Features

Explore the powerful features of the TypeScript SDK:

Automatic Retries

Smart retry mechanism for handling transient failures with configurable retry policies.

typescript
// Configure retry behavior
const fyn = new Fyn({
  retry: {
    maxRetries: 3,        // Maximum retry attempts
    initialDelay: 1000,   // Initial delay in ms
    maxDelay: 5000,       // Maximum delay cap
    backoffFactor: 2      // Exponential backoff multiplier
  }
});

// Retry behavior in action
try {
  const link = await fyn.links.get('link_123');
} catch (error) {
  if (error instanceof RetryError) {
    console.log(`Failed after ${error.attempts} attempts`);
    console.log('Last error:', error.lastError);
    console.log('Total time:', error.totalTime);
  }
}

Caching Strategy

Sophisticated caching system with automatic ETag handling and performance optimization.

typescript
// Configure caching behavior
const fyn = new Fyn({
  cache: {
    enabled: true,           // Enable/disable caching
    maxSize: 1000,          // Maximum cache entries
    ttl: '1h',              // Cache TTL
    staleWhileRevalidate: true
  }
});

// Cache in action
const link = await fyn.links.get('link_123', {
  cache: {
    ttl: '5m',              // Override default TTL
    staleWhileRevalidate: true,
    tags: ['link', 'user_123']
  }
});

// Cache operations
await fyn.cache.invalidate('link_123');    // Single entry
await fyn.cache.invalidateTag('link');     // By tag
await fyn.cache.clear();                   // Full clear

// Cache statistics
const stats = fyn.cache.getStats();
console.log({
  hits: stats.hits,
  misses: stats.misses,
  hitRate: stats.hitRate,
  size: stats.size,
  avgAccessTime: stats.avgAccessTime
});

Performance Metrics

Built-in performance monitoring with detailed metrics and statistics.

typescript
// Get detailed performance metrics
const metrics = await fyn.metrics.get({
  timeframe: '5m',    // Last 5 minutes
  resolution: '1m'    // 1-minute buckets
});

// Sample metrics response
{
  requests: {
    total: 150,
    success: 148,
    failed: 2,
    successRate: 98.67
  },
  timing: {
    avg: 245.5,      // ms
    p95: 450.2,      // 95th percentile
    p99: 850.1       // 99th percentile
  },
  rateLimit: {
    remaining: 850,
    reset: 1678892400,
    limit: 1000
  },
  cache: {
    hits: 45,
    misses: 15,
    hitRatio: 75.0,
    size: 250,
    evictions: 5
  },
  errors: {
    byType: {
      network: 1,
      validation: 1,
      server: 0
    },
    topEndpoints: [
      { path: '/links', count: 1 },
      { path: '/analytics', count: 1 }
    ]
  }
}

Type Definitions

The SDK comes with comprehensive TypeScript definitions for a great development experience:

typescript
interface FynlinkClientOptions {
  apiKey: string;
  cache?: {
    maxSize?: number;    // Maximum number of items to cache
    ttl?: string;        // Time to live for cached items
    enabled?: boolean;   // Enable/disable caching
  };
  retry?: {
    maxRetries?: number;      // Maximum number of retry attempts
    initialDelay?: number;    // Initial delay between retries (ms)
    maxDelay?: number;        // Maximum delay between retries (ms)
    backoffFactor?: number;   // Exponential backoff factor
  };
}

interface CreateUrlOptions {
  longUrl: string;          // The URL to shorten
  expiresIn?: string;       // Expiration time (e.g., '24h', '7d')
  password?: string;        // Password protection
  customPath?: string;      // Custom short URL path
  domain?: string;          // Custom domain
  title?: string;           // URL title
  description?: string;     // URL description
}

interface UrlAnalytics {
  clicks: number;           // Total number of clicks
  countries: Record<string, number>;    // Clicks by country
  devices: Record<string, number>;      // Clicks by device
  browsers: Record<string, number>;     // Clicks by browser
  referrers: Record<string, number>;    // Clicks by referrer
  timeframes: {
    last24h: number;        // Clicks in last 24 hours
    last7d: number;         // Clicks in last 7 days
    last30d: number;        // Clicks in last 30 days
  };
}

// Strongly typed error handling
interface FynlinkError extends Error {
  code: 'INVALID_URL' | 'RATE_LIMIT' | 'NETWORK_ERROR' | 'UNAUTHORIZED';
  status: number;
  retryAttempt?: number;
  nextRetryDelay?: number;
  details?: Record<string, any>;
}
E2EE
Your link data is encrypted, even before leaving the browser & can be decrypted only by you.
< 200ms
Average link redirection time, depends mainly on location of the end user.
99.99%
Uptime guarantee for our redirection services.
300+
For quick, uninterrupted URL redirection, our redirection service is available on all major cities worldwide.