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 🙏

© 2025 – Pkg Stats / Ryan Hefner

wolfdog-request-manager

v4.1.1

Published

Universal HTTP request manager with TypeScript support and configurable environment support

Readme

wolfdog-request-manager

npm version GitLab CI/CD Coverage

Universal HTTP request manager with TypeScript support and customizable error handling for web and React Native applications.

Features

  • 🌐 Universal: Works in both browser and React Native environments
  • 📝 TypeScript: Full TypeScript support with type safety
  • 🔧 Configurable: Customizable error handling and storage
  • 🗄️ Smart Storage: Configurable storage (localStorage/AsyncStorage/custom)
  • 📁 File Upload: Built-in support for file uploads with size validation
  • 🚫 Request Cancellation: Support for canceling requests
  • 📊 Response Mapping: Flexible response data mapping with default values
  • 🐛 Error Logging: Built-in error logging and handling

Installation

Using npm

npm install wolfdog-request-manager

Using yarn

yarn add wolfdog-request-manager

Setup for React Native

For React Native projects, you'll also need to install the peer dependency:

Using npm:

npm install @react-native-async-storage/async-storage

Using yarn:

yarn add @react-native-async-storage/async-storage

Import Options

The library provides multiple ways to import and use its functionality:

Option 1: Using the main RequestManager object (recommended)

import { RequestManager } from 'wolfdog-request-manager';

// All utilities are available through RequestManager
RequestManager.configure({ 
  serverUrl: 'https://api.example.com',
  environment: 'browser'
});
const result = await RequestManager.performRequest(/* ... */);
RequestManager.LogsHelper.clearLogs();
RequestManager.ErrorHandler.handleErrors(error);

Option 2: Named imports for specific utilities

import { 
  RequestManager, 
  configure, 
  LogsHelper, 
  ErrorHandler 
} from 'wolfdog-request-manager';

configure({ 
  serverUrl: 'https://api.example.com',
  environment: 'browser'
});
const result = await RequestManager.performRequest(/* ... */);
LogsHelper.clearLogs();

Option 3: Default import

import RequestManager from 'wolfdog-request-manager';

RequestManager.configure({ 
  serverUrl: 'https://api.example.com',
  environment: 'browser'
});
const result = await RequestManager.performRequest(/* ... */);

Quick Start

1. Configure the library

import { RequestManager } from 'wolfdog-request-manager';

RequestManager.configure({
  serverUrl: 'https://api.example.com',
  environment: 'browser' // or 'react-native'
});

2. Make your first request

import { RequestManager } from 'wolfdog-request-manager';

// Define the expected response structure
interface UserResponse {
  id: number;
  name: string;
  email: string;
}

// Make a GET request
const result = await RequestManager.performRequest<UserResponse>({
  type: 'GET',
  url: '/users/1',
  errorOptions: {
    defaultEnd: 'fetching user data'
  },
  responseData: {
    id: { defaultValue: 0 },
    name: { defaultValue: '', path: 'user.name' },
    email: { defaultValue: '', path: 'user.email' }
  }
});

if (result.ok) {
  console.log('User:', result.data);
} else {
  console.error('Error:', result.message);
}

API Reference

RequestManager.performRequest(props)

Performs an HTTP request with the specified configuration.

Parameters

  • type: HTTP method ('GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE')
  • url: Request URL (relative to configured serverUrl)
  • errorOptions: Error handling configuration
  • responseData: Response data mapping configuration
  • query?: Query parameters object
  • body?: Request body (for POST/PUT/PATCH requests)
  • contentType?: Content type ('application/json' | 'multipart/form-data')
  • logResponse?: Enable response logging (logs with [RESPONSE] prefix)
  • logFormData?: Enable FormData logging (useful for debugging file uploads)
  • cancelToken?: Enable request cancellation
  • maxFileSizeInMb?: Maximum file size for uploads

Response

Returns a Promise that resolves to:

{
  ok: boolean;           // Request success status
  status: number;        // HTTP status code
  message: string;       // Success/error message
  isNetworkError: boolean; // Network error indicator
  data: T;              // Mapped response data
  requestData: {
    url: string;        // Final request URL
  }
}

Usage Examples

GET Request with Query Parameters

const result = await RequestManager.performRequest({
  type: 'GET',
  url: '/users',
  query: {
    page: 1,
    limit: 10,
    search: 'john'
  },
  errorOptions: {
    defaultEnd: 'fetching users'
  },
  responseData: {
    users: { defaultValue: [], path: 'data' },
    total: { defaultValue: 0, path: 'meta.total' }
  }
});

POST Request with JSON Body

const result = await RequestManager.performRequest({
  type: 'POST',
  url: '/users',
  contentType: 'application/json',
  logResponse: true, // Logs response with [RESPONSE] prefix
  body: {
    name: 'John Doe',
    email: '[email protected]'
  },
  errorOptions: {
    defaultEnd: 'creating user',
    on409: 'User with this email already exists'
  },
  responseData: {
    user: { defaultValue: null, path: 'data' }
  }
});

Note: Setting logResponse: true will log the response data to console with [RESPONSE] prefix, helpful for debugging API responses.

File Upload

const result = await RequestManager.performRequest({
  type: 'POST',
  url: '/upload',
  contentType: 'multipart/form-data',
  maxFileSizeInMb: 10,
  logFormData: true, // Enable to see FormData contents in console
  body: {
    file: {
      localUrl: '/path/to/file.jpg',
      size: 1024000,
      type: 'image/jpeg'
    },
    description: 'Profile picture'
  },
  errorOptions: {
    defaultEnd: 'uploading file'
  },
  responseData: {
    fileUrl: { defaultValue: '', path: 'url' }
  }
});

Note: Setting logFormData: true will log all FormData entries to the console, which is helpful for debugging file uploads and form submissions.

Custom Response Data Mapping

const result = await RequestManager.performRequest({
  type: 'GET',
  url: '/user/profile',
  errorOptions: {
    defaultEnd: 'fetching profile'
  },
  responseData: {
    // Simple path mapping
    id: { defaultValue: 0, path: 'user.id' },
    
    // Custom transformation function
    displayName: {
      defaultValue: 'Unknown User',
      valueFromFunction: (data) => `${data.user.firstName} ${data.user.lastName}`
    },
    
    // Root level data
    isActive: { defaultValue: false }
  }
});

JWT Management Functions

RequestManager.JWT.setJWT(token)

Sets the JWT token for authentication.

RequestManager.JWT.setJWT('your-jwt-token');
RequestManager.JWT.setJWT('Bearer your-jwt-token'); // Bearer prefix optional
RequestManager.JWT.setJWT(null); // Clear token

RequestManager.JWT.getJWT()

Returns the currently set JWT token.

const token = RequestManager.JWT.getJWT(); // string | null

RequestManager.JWT.clearJWT()

Clears the currently set JWT token.

RequestManager.JWT.clearJWT();

Alternative imports:

import { setJWT, getJWT, clearJWT } from 'wolfdog-request-manager';

setJWT('token');
const token = getJWT();
clearJWT();

RequestManager.JWT.setJWTInStorage(token)

Saves JWT token to persistent storage.

await RequestManager.JWT.setJWTInStorage('your-jwt-token');
await RequestManager.JWT.setJWTInStorage(null); // Remove from storage

RequestManager.JWT.getJWTFromStorage()

Retrieves JWT token from persistent storage.

const token = await RequestManager.JWT.getJWTFromStorage(); // string | null

RequestManager.JWT.clearJWTFromStorage()

Clears JWT token from persistent storage.

await RequestManager.JWT.clearJWTFromStorage();

RequestManager.JWT.clearJWTFromStorage()

Removes JWT token from persistent storage.

await RequestManager.JWT.clearJWTFromStorage();

Alternative imports for storage functions:

import { setJWTInStorage, getJWTFromStorage, clearJWTFromStorage } from 'wolfdog-request-manager';

await setJWTInStorage('token');
const token = await getJWTFromStorage();
await clearJWTFromStorage();

Configuration

Global Configuration

import { configure, appConfig } from 'wolfdog-request-manager';

// Set configuration
configure({
  serverUrl: 'https://api.example.com'
});

// Access current configuration
console.log(appConfig.serverUrl);

// Update serverUrl directly
appConfig.serverUrl = 'https://new-api.example.com';

Custom Messages Configuration

You can customize all error and system messages used by the library:

import { configure } from 'wolfdog-request-manager';

// Configure with custom messages (e.g., Polish)
configure({
  serverUrl: 'https://api.example.com',
  messages: {
    defaultError: 'Coś poszło nie tak. Spróbuj ponownie później.',
    networkError: 'Brak połączenia z serwerem. Spróbuj ponownie później.',
    loginError: 'Błąd logowania. Spróbuj uruchomić aplikację ponownie.',
    serverError: 'Wystąpiła awaria serwera',
    objectExists: 'Taki obiekt już istnieje',
    notFound: 'Nie znaleziono',
    accessDenied: 'Nie możesz tego zrobić',
    requestCanceled: 'Anulowano żądanie',
    fileTooLarge: 'Plik jest za duży. Maksymalny rozmiar to {maxSize}MB.',
    successNoData: 'Sukces - nie zwrócono danych',
    success: 'sukces',
    somethingWentWrongDuring: 'Coś poszło nie tak podczas {action}'
  }
});

Customizable messages:

  • defaultError - Generic error message
  • networkError - Network connection errors
  • loginError - Authentication errors
  • serverError - 500 status errors
  • objectExists - 409 conflict errors
  • notFound - 404 errors
  • accessDenied - 403 forbidden errors
  • requestCanceled - Canceled request messages
  • fileTooLarge - File upload size errors (supports {maxSize} parameter)
  • successNoData - Success with no response data
  • success - Generic success message
  • somethingWentWrongDuring - Contextual error messages (supports {action} parameter)

Partial configuration:

import { configure } from 'wolfdog-request-manager';

// You can configure only specific messages
configure({
  serverUrl: 'https://api.example.com',
  messages: {
    defaultError: 'Wystąpił błąd',
    networkError: 'Brak internetu',
    notFound: 'Nie znaleziono zasobu'
    // Other messages will use English defaults
  }
});

Using parameterized messages: Some messages support parameters (marked with {paramName}):

import { formatMessage } from 'wolfdog-request-manager';

const message = formatMessage('File too large. Max: {maxSize}MB', { maxSize: 10 });
// Result: "File too large. Max: 10MB"

Environment Configuration

Required: You must specify the environment for proper storage functionality:

import { configure } from 'wolfdog-request-manager';

// For React Native apps
configure({
  serverUrl: 'https://api.example.com',
  environment: 'react-native'  // Required
});

// For browser/web apps  
configure({
  serverUrl: 'https://api.example.com',
  environment: 'browser'  // Required
});

Environment options:

  • 'react-native' - Uses AsyncStorage for data persistence
  • 'browser' - Uses localStorage for data persistence

Why environment configuration is important:

  • Ensures proper storage mechanism selection
  • Prevents runtime errors with localStorage in React Native
  • Enables reliable JWT token persistence
  • Optimizes performance for the target platform

Manual storage override (advanced):

import AsyncStorage from '@react-native-async-storage/async-storage';
import { StorageController } from 'wolfdog-request-manager';

// Custom storage implementation
const customStorage = {
  getValue: AsyncStorage.getItem,
  setValue: AsyncStorage.setItem,
  removeValue: AsyncStorage.removeItem,
};

StorageController.setStorage(customStorage);

Configuration Warnings

The library will automatically warn you if important configuration is missing:

import { RequestManager } from 'wolfdog-request-manager';

// If you forget to configure serverUrl
const result = await RequestManager.performRequest({
  type: 'GET',
  url: '/users',
  errorOptions: {},
  responseData: { id: { defaultValue: 0 } }
});

// Console output: ⚠️ RequestManager: serverUrl is not configured! 
// Please call configure({ serverUrl: "your-api-url" }) before making requests.

What triggers warnings:

  • Empty or missing serverUrl configuration
  • Whitespace-only serverUrl values

To fix warnings:

import { configure } from 'wolfdog-request-manager';

// Properly configure before making requests
configure({
  serverUrl: 'https://api.example.com'
});

JWT Token Management

The library provides convenient methods to manage JWT tokens for authentication:

import { RequestManager, setJWT, getJWTToken, clearJWT } from 'wolfdog-request-manager';

// Method 1: Using RequestManager JWT namespace
RequestManager.JWT.setJWT('your-jwt-token');
RequestManager.JWT.setJWT('Bearer your-jwt-token'); // Bearer prefix is optional

// Method 2: Using direct imports
setJWT('your-jwt-token');

// Get current token
const currentToken = RequestManager.JWT.getJWT();
// or
const currentToken = getJWT();

// Clear token
RequestManager.JWT.clearJWT();
// or
clearJWT();

Token Priority:

  1. Manually set token (via setJWT()) - highest priority
  2. Stored token (from storage under "request-manager-jwt" key) - fallback

Token Format:

  • The library automatically adds Bearer prefix if not present
  • If your token already has Bearer prefix, it won't be duplicated

Usage Examples:

import { RequestManager } from 'wolfdog-request-manager';

// Configure the library
RequestManager.configure({
  serverUrl: 'https://api.example.com'
});

// Set JWT token after user login
RequestManager.JWT.setJWT('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...');

// Make authenticated requests
const result = await RequestManager.performRequest({
  type: 'GET',
  url: '/protected-resource',
  errorOptions: {},
  responseData: {
    data: { defaultValue: null }
  }
});

// Clear token on logout
RequestManager.JWT.clearJWT();

Storage Management: The library also provides functions to directly manage JWT tokens in storage:

import { RequestManager, setJWTInStorage, getJWTFromStorage, clearJWTFromStorage } from 'wolfdog-request-manager';

// Save token to storage (persists between sessions)
await RequestManager.JWT.setJWTInStorage('your-jwt-token');
// or
await setJWTInStorage('your-jwt-token');

// Get token from storage
const storedToken = await RequestManager.JWT.getJWTFromStorage();
// or
const storedToken = await getJWTFromStorage();

// Clear token from storage
await RequestManager.JWT.clearJWTFromStorage();
// or
await clearJWTFromStorage();
// or (alternative)
await RequestManager.JWT.setJWTInStorage(null);

Note: Tokens are stored under the key "request-manager-jwt" to avoid conflicts with other libraries.

Custom Storage Implementation

import { StorageController, IStorage } from 'wolfdog-request-manager';

class CustomStorage implements IStorage {
  async getValue(key: string): Promise<string | null> {
    // Your custom storage logic
    return null;
  }
  
  async setValue(key: string, value: string): Promise<void> {
    // Your custom storage logic
  }
  
  async removeValue(key: string): Promise<void> {
    // Your custom storage logic
  }
}

// Use custom storage
StorageController.setStorage(new CustomStorage());

Error Handling

The library provides comprehensive error handling with customizable messages:

const errorOptions = {
  defaultEnd: 'processing request',     // Default error suffix
  on404: 'Resource not found',         // Custom 404 message
  on403: 'Access denied',              // Custom 403 message
  on401: 'Please log in again',        // Custom 401 message
  on409: 'Resource already exists',    // Custom 409 message
  on500: 'Server error occurred'       // Custom 500 message
};

Logging

Access request logs using the LogsHelper:

import { LogsHelper, type LogType } from 'wolfdog-request-manager';

// Get all logs
const logs = await LogsHelper.getAllLogs();

// Clear logs
await LogsHelper.clearLogs();

LogType

The logs returned by getAllLogs() have the following structure:

type LogType = {
  value: string;      // The log message content
  createdAt: string;  // ISO timestamp when the log was created
}

Usage example:

import { LogsHelper, type LogType } from 'wolfdog-request-manager';

const logs: LogType[] = await LogsHelper.getAllLogs();

logs.forEach((log: LogType) => {
  console.log(`[${log.createdAt}] ${log.value}`);
});

// Example output:
// [2023-10-27T10:30:45.123Z] Error occurred during request
// [2023-10-27T10:30:50.456Z] Request completed successfully

TypeScript Support

The library is built with TypeScript and provides full type safety:

import type {
  IPerformRequest,
  ContentTypeOption,
  ResponseDataMap,
  IErrorOptions,
  AppConfig,
  AppEnvironment,
  LogType
} from 'wolfdog-request-manager';

VS Code Snippets

For faster development, you can add these snippets to your VS Code TypeScript snippets file:

How to add snippets:

  1. Open VS Code
  2. Press Ctrl+Shift+P (or Cmd+Shift+P on Mac)
  3. Type "Configure User Snippets"
  4. Select "TypeScript" or "TypeScript React"
  5. Add the following snippet to your typescript.json file:
{
  "create perform request": {
    "prefix": "create-perform-request",
    "body": [
      "type ${1:ResponseType} = {}",
      "",
      "const ${2:requestFunction} = async () => {",
      "\tconst result = await RequestManager.performRequest<${1:ResponseType}>({",
      "\t\ttype: '${3|GET,POST,PUT,PATCH,DELETE|}',",
      "\t\turl: '${4:/api/endpoint}',",
      "\t\tresponseData: {",
      "\t\t\t${5:// Add your response mapping here}",
      "\t\t},",
      "\t\terrorOptions: {",
      "\t\t\tdefaultEnd: '${6:performing request}',",
      "\t\t},",
      "\t});",
      "",
      "\tif (result.ok) {",
      "\t\tconsole.log('Success:', result.data);",
      "\t} else {",
      "\t\tconsole.error('Error:', result.message);",
      "\t}",
      "",
      "\treturn result;",
      "};"
    ],
    "description": "Create a new RequestManager performRequest function"
  }
}

Usage:

After adding the snippet, type create-perform-request in any TypeScript file and press Tab to generate a complete request template.

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.