Socket
Socket
Sign inDemoInstall

adapters.ts

Package Overview
Dependencies
71
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    adapters.ts

Quick, easy and type-safe way for declarative http endpoint definitions.


Version published
Weekly downloads
1
Maintainers
1
Created
Weekly downloads
 

Readme

Source

adapters.ts

Quick, easy and type-safe way for declarative http endpoint definitions.

Quick Start

By default adapters.ts provides two ready to use adapter classes:

  • FetchAdapter that leverages the native browser fetch API
  • AxiosAdapter that leverages the Axios library (axios needs to be installed separately)

but any http client library can be used with adapters.ts.

Define a simple axios adapter

import { AxiosAdapter } from "adapters.ts";

class SwapiStarship extends AxiosAdapter {
  // must be a readonly
  static readonly URL_TEMPLATE = "https://swapi.dev/api/starships/{id}";
}

// SwapiStarship: {
//  get(urlParams: { id: string }, options?: { config?: AxiosRequestConfig }): Promise<AxiosResponse>;
//  post(urlParams: { id: string }, options?: { config?: AxiosRequestConfig }): Promise<AxiosResponse>;
//  put(urlParams: { id: string }, options?: { config?: AxiosRequestConfig }): Promise<AxiosResponse>;
//  patch(urlParams: { id: string }, options?: { config?: AxiosRequestConfig }): Promise<AxiosResponse>;
//  delete(urlParams: { id: string }, options?: { config?: AxiosRequestConfig }): Promise<AxiosResponse>;
//  options(urlParams: { id: string }, options?: { config?: AxiosRequestConfig }): Promise<AxiosResponse>;
// }

// send a get request
SwapiStarship.get({ id: "1" }).then(
  (response /* AxiosResponse<any, any> */) => {
    console.log(response.data);
  }
);

Adapter with type guards on received data

import { AxiosAdapter, DataType } from "adapters.ts";

class SwapiStarship extends AxiosAdapter {
  static readonly URL_TEMPLATE = "https://swapi.dev/api/starships/{id}";

  static GET_RESPONSE_TYPE_DEF = DataType.RecordOf({
    name: DataType.String,
    model: DataType.String,
    /* ... */
  });
}

// SwapiStarship: {
//  get(
//    urlParams: { id: string },
//    options?: { config?: AxiosRequestConfig }
//  ): Promise<AxiosResponse<{name: string; model: string; }>>;
//
//  post(urlParams: { id: string }, options?: { config?: AxiosRequestConfig }): Promise<AxiosResponse>;
//  ...
// }

// send a request
SwapiStarship.get({ id: "1" }).then(
  (response /* AxiosResponse<{name: string, model: string, ...}, any> */) => {
    console.log(response.data);
  }
);

Adapter with type guards on sent data

import { AxiosAdapter, DataType } from "adapters.ts";

class SwapiStarship extends AxiosAdapter {
  static readonly URL_TEMPLATE = "https://swapi.dev/api/starships";

  static POST_REQUEST_TYPE_DEF = DataType.RecordOf({
    name: DataType.String,
    model: DataType.String,
    /* ... */
  });
}

// SwapiStarship: {
//  get(options?: { config?: AxiosRequestConfig }): Promise<AxiosResponse>;
//
//  post(
//    options: {
//      data: {
//        name: string;
//        model: string;
//      };
//      config?: AxiosRequestConfig;
//    }
//  ): Promise<AxiosResponse>;
//  ...
// }

// send a request
SwapiStarship.post({
  // Provided data must have a type that matches the definition in the above class
  data: {
    name: "CR90 Corvette",
    model: "CR90 Corvette",
  },
});

Disable/enable data validation on requests and responses

import { AxiosAdapter } from "adapters.ts";

class MyAdapter extends AxiosAdapter {
  static readonly URL_TEMPLATE = "https://url-goes.here";

  // set this to true to validate all incoming requests against
  // the below type definitions, or to false to not validate at all
  // default is `false`
  static VALIDATE_REQUESTS = true;

  static DELETE_REQUEST_TYPE_DEF = /* some type definition */;
  static GET_REQUEST_TYPE_DEF = /* some type definition */;
  static OPTIONS_REQUEST_TYPE_DEF = /* some type definition */;
  static PATCH_REQUEST_TYPE_DEF = /* some type definition */;
  static POST_REQUEST_TYPE_DEF = /* some type definition */;
  static PUT_REQUEST_TYPE_DEF = /* some type definition */;

  // set this to true to validate all incoming requests against
  // the below type definitions, or to false to not validate at all
  // default is `true`
  static VALIDATE_RESPONSES = true;

  static DELETE_RESPONSE_TYPE_DEF = /* some type definition */;
  static GET_RESPONSE_TYPE_DEF = /* some type definition */;
  static OPTIONS_RESPONSE_TYPE_DEF = /* some type definition */;
  static PATCH_RESPONSE_TYPE_DEF = /* some type definition */;
  static POST_RESPONSE_TYPE_DEF = /* some type definition */;
  static PUT_RESPONSE_TYPE_DEF = /* some type definition */;
}

Specify an axios instance for the adapter

To use a specific axios instance:

import { AxiosAdapter, AxiosXHR } from "adapters.ts";

const myAxiosInstance = axios.create();

class SwapiStarship extends AxiosAdapter {
  protected static readonly xhr = new AxiosXHR(myAxiosInstance);

  static URL_TEMPLATE = "https://swapi.dev/api/starships/{id}";
}

Define new adapter with a http client of your choice

First a class implementing an adapters.ts XHRInterface will be necessary. This class will be used to send actual request and retrieve the payload for validation.

(for reference here is the default axios xhr interface)

import type { XHRInterface, _, RequestMethod } from "adapters.ts";

type MyHTTPClientResponse<T> = {
  data: T; // response payload
  status: number; // ex. 404, 200 etc
};

type MyHTTPClientConfig = {
  /* ... */
};

const MyHTTPClientInstance = new MyHTTPClient(); // a hypothetical http client

class MyHTTPClientXHR<T = _> implements XHRInterface<MyHTTPClientResponse<T>> {
  async sendRequest(params: {
    method: RequestMethod;
    url: string;
    data?: Record<string, any>;
    config?: MyHTTPClientConfig;
  }): Promise<MyHTTPClientResponse<T>> {
    return MyHTTPClientInstance.sendHttpRequest<T>(/* ... */);
  }

  async extractPayload(response: MyHTTPClientResponse<T>): Promise<T> {
    return response.data;
  }
}

Provide the XHRInterface class instance to the Adapter:

import { BaseAdapter } from "adapters.ts";

class MyHTTPClientAdapter extends BaseAdapter {
  protected static readonly xhr = new MyHTTPClientXHR();
}

The MyHTTPClientAdapter can be then used in the same way as AxiosAdapter or FetchAdapter.

Keywords

FAQs

Last updated on 23 Jun 2022

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc