or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

errors.mdhooks.mdhttp-methods.mdindex.mdinstances.mdoptions.mdpagination.mdresponses.mdstreams.mdutilities.md
tile.json

instances.mddocs/

Instance Management

Create and extend Got instances with custom defaults and configurations for reusable HTTP clients with shared settings and behavior.

Capabilities

Creating Instances

Factory function for creating new Got instances with custom default configurations.

/**
 * Create a new Got instance with custom defaults
 * @param defaults - Default configuration for the instance
 * @returns New Got instance
 */
function create(defaults: InstanceDefaults): Got;

/**
 * Instance defaults configuration
 */
interface InstanceDefaults {
  /**
   * Default options for all requests
   */
  options: Options;
  
  /**
   * Array of handler functions executed for each request
   * @default []
   */
  handlers: HandlerFunction[];
  
  /**
   * Whether defaults can be modified after creation
   * @default false
   */
  mutableDefaults: boolean;
}

/**
 * Handler function for customizing request processing
 */
type HandlerFunction = <T extends GotReturn>(
  options: Options,
  next: (options: Options) => T
) => T | Promise<T>;

Usage Examples:

import { create, Options } from "got";

// Create instance with API base URL and auth
const api = create({
  options: new Options({
    prefixUrl: "https://api.example.com",
    headers: {
      "Authorization": "Bearer your-token-here",
      "User-Agent": "MyApp/1.0"
    },
    timeout: { request: 10000 },
    retry: { limit: 3 }
  }),
  handlers: [],
  mutableDefaults: false
});

// Use the instance
const users = await api.get("users").json();
const user = await api.post("users", {
  json: { name: "Alice", email: "alice@example.com" }
}).json();

Extending Instances

Create new instances by extending existing ones with additional or modified configuration.

/**
 * Instance extension interface
 */
interface Got {
  /**
   * Create extended instance with merged configuration
   * @param instancesOrOptions - Instances or options to merge
   * @returns New extended Got instance
   */
  extend<T extends Array<Got | ExtendOptions>>(...instancesOrOptions: T): Got<MergeExtendsConfig<T>>;
  
  /**
   * Access to instance defaults
   */
  defaults: InstanceDefaults;
}

/**
 * Options for extending instances
 */
interface ExtendOptions extends OptionsInit {
  /**
   * Handler functions for request processing
   */
  handlers?: HandlerFunction[];
  
  /**
   * Whether defaults are mutable
   */
  mutableDefaults?: boolean;
}

Usage Examples:

import got from "got";

// Create base API client
const api = got.extend({
  prefixUrl: "https://api.example.com",
  headers: {
    "User-Agent": "MyApp/1.0"
  },
  timeout: { request: 10000 }
});

// Extend for authenticated requests
const authenticatedApi = api.extend({
  headers: {
    "Authorization": "Bearer token123"
  }
});

// Extend for specific service
const userService = authenticatedApi.extend({
  prefixUrl: "https://api.example.com/users",
  responseType: "json",
  resolveBodyOnly: true
});

// Use extended instances
const users = await userService.get(""); // GET /users
const user = await userService.get("123"); // GET /users/123

Instance Defaults

Access and inspect instance configuration and defaults.

/**
 * Instance defaults object
 */
interface InstanceDefaults {
  /**
   * Default options used by the instance
   */
  readonly options: Options;
  
  /**
   * Handler functions executed for each request
   */
  readonly handlers: readonly HandlerFunction[];
  
  /**
   * Whether the defaults can be modified
   */
  readonly mutableDefaults: boolean;
}

Usage Examples:

import got from "got";

const api = got.extend({
  prefixUrl: "https://api.example.com",
  headers: { "Authorization": "Bearer token" }
});

// Inspect instance defaults
console.log("Base URL:", api.defaults.options.prefixUrl);
console.log("Headers:", api.defaults.options.headers);
console.log("Handlers count:", api.defaults.handlers.length);
console.log("Mutable:", api.defaults.mutableDefaults);

// Create new instance with modified defaults
const newApi = api.extend({
  timeout: { request: 5000 }
});

Handler Functions

Custom handler functions for request processing and middleware-like functionality.

/**
 * Handler function signature
 * @param options - Request options
 * @param next - Function to call next handler or make request
 * @returns Request result or promise
 */
type HandlerFunction = <T extends GotReturn>(
  options: Options,
  next: (options: Options) => T
) => T | Promise<T>;

/**
 * Got return type (Request or CancelableRequest)
 */
type GotReturn = Request | CancelableRequest;

Usage Examples:

import got, { create, Options } from "got";

// Logging handler
const loggingHandler: HandlerFunction = (options, next) => {
  console.log(`Making request to: ${options.url}`);
  const start = Date.now();
  
  const result = next(options);
  
  if (result instanceof Promise) {
    return result.then(response => {
      console.log(`Request completed in ${Date.now() - start}ms`);
      return response;
    });
  }
  
  return result;
};

// Retry handler
const retryHandler: HandlerFunction = async (options, next) => {
  const maxRetries = 3;
  let lastError: Error;
  
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await next(options);
    } catch (error) {
      lastError = error;
      if (attempt === maxRetries) break;
      
      // Wait before retry
      await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
    }
  }
  
  throw lastError;
};

// Create instance with handlers
const api = create({
  options: new Options({ prefixUrl: "https://api.example.com" }),
  handlers: [loggingHandler, retryHandler],
  mutableDefaults: false
});

Composing Instances

Combine multiple instances to create complex configurations.

import got from "got";

// Base configuration
const baseApi = got.extend({
  timeout: { request: 10000 },
  retry: { limit: 2 }
});

// Authentication configuration
const authConfig = got.extend({
  headers: {
    "Authorization": "Bearer token123"
  }
});

// JSON configuration
const jsonConfig = got.extend({
  responseType: "json",
  resolveBodyOnly: true,
  headers: {
    "Content-Type": "application/json"
  }
});

// Compose all configurations
const apiClient = got.extend(baseApi, authConfig, jsonConfig, {
  prefixUrl: "https://api.example.com"
});

// Use composed client
const users = await apiClient.get("users");
const newUser = await apiClient.post("users", {
  json: { name: "Alice" }
});

Mutable Defaults

Create instances with mutable defaults that can be updated at runtime.

import { create, Options } from "got";

// Create instance with mutable defaults
const api = create({
  options: new Options({
    prefixUrl: "https://api.example.com",
    headers: { "Authorization": "Bearer initial-token" }
  }),
  handlers: [],
  mutableDefaults: true
});

// Update token at runtime
api.defaults.options.headers["Authorization"] = "Bearer new-token";

// Or update entire header object
Object.assign(api.defaults.options.headers, {
  "Authorization": "Bearer updated-token",
  "X-Client-Version": "1.2.0"
});

// Use updated instance
const response = await api.get("protected-resource");

Warning: Mutable defaults should be used carefully as they can lead to unexpected behavior in concurrent scenarios.

Instance Patterns

Service-specific clients:

import got from "got";

// Base API configuration
const baseApi = got.extend({
  prefixUrl: "https://api.example.com",
  headers: {
    "Authorization": "Bearer token",
    "User-Agent": "MyApp/1.0"
  },
  timeout: { request: 10000 },
  retry: { limit: 3 }
});

// User service
export const userService = baseApi.extend({
  prefixUrl: "https://api.example.com/users",
  responseType: "json",
  resolveBodyOnly: true
});

// Order service  
export const orderService = baseApi.extend({
  prefixUrl: "https://api.example.com/orders",
  responseType: "json",
  resolveBodyOnly: true
});

// Usage
const users = await userService.get("");      // GET /users
const user = await userService.get("123");    // GET /users/123
const orders = await orderService.get("");    // GET /orders

Environment-specific clients:

import got from "got";

const createApiClient = (environment: string) => {
  const baseUrls = {
    development: "https://dev-api.example.com",
    staging: "https://staging-api.example.com",
    production: "https://api.example.com"
  };
  
  return got.extend({
    prefixUrl: baseUrls[environment],
    headers: {
      "User-Agent": `MyApp/1.0 (${environment})`
    },
    timeout: {
      request: environment === "development" ? 30000 : 10000
    },
    retry: {
      limit: environment === "production" ? 3 : 1
    }
  });
};

// Create environment-specific clients
export const devApi = createApiClient("development");
export const prodApi = createApiClient("production");

Plugin pattern:

import got from "got";

// Plugin for adding API key authentication
const withApiKey = (apiKey: string) => got.extend({
  headers: {
    "X-API-Key": apiKey
  }
});

// Plugin for adding request logging
const withLogging = () => got.extend({
  hooks: {
    beforeRequest: [
      (options) => {
        console.log(`→ ${options.method} ${options.url}`);
      }
    ],
    afterResponse: [
      (response) => {
        console.log(`← ${response.statusCode} ${response.requestUrl}`);
        return response;
      }
    ]
  }
});

// Plugin for adding retry logic
const withRetry = (maxRetries: number = 3) => got.extend({
  retry: {
    limit: maxRetries,
    methods: ["GET", "PUT", "HEAD", "DELETE", "OPTIONS", "TRACE"],
    statusCodes: [408, 413, 429, 500, 502, 503, 504]
  }
});

// Compose plugins
const api = got
  .extend(withApiKey("your-api-key"))
  .extend(withLogging())
  .extend(withRetry(5))
  .extend({
    prefixUrl: "https://api.example.com"
  });

Type Safety with Extensions

Maintain type safety when extending instances with custom configurations.

/**
 * Type for merging extend configurations
 */
type MergeExtendsConfig<T extends Array<Got | ExtendOptions>> = /* complex type merging logic */;

/**
 * Extract extend options from Got instance or options
 */
type ExtractExtendOptions<T> = T extends Got<infer GotOptions> ? GotOptions : T;

Usage:

import got from "got";

// Typed API client
interface ApiResponse<T> {
  data: T;
  status: "success" | "error";
  message?: string;
}

const typedApi = got.extend({
  prefixUrl: "https://api.example.com",
  responseType: "json",
  resolveBodyOnly: true
});

// Type-safe usage
const response = await typedApi.get("users") as ApiResponse<User[]>;
const user = await typedApi.post("users", {
  json: { name: "Alice" }
}) as ApiResponse<User>;