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 🙏

© 2024 – Pkg Stats / Ryan Hefner

typesafe-fetch

v1.0.1

Published

Type-Safe version of fetch that uses OpenAPI TypeScript definitions to check API calls at compile type.

Downloads

4

Readme

Type-Safe Fetch

Given a path and a method, the TypeScript compiler will guarantee that you are passing the correct path and query parameters, and the correct body (and only if needed) + it will return the correct type for the response object!

Realised already how insanely awesome that is? The compiler will validate every aspect of the API request, including the response type - automatically!

Bonus: Tiny library (~1kb) with 0 dependencies.

Demo

Using typesafe-fetch with the Petstore demo API in VS Code to see the compiler suggested completions.

Screen capture

Usage

Install:

npm install typesafe-fetch

yarn add typesafe-fetch

Setup:

import getSafeFetch, { FetchFunction } from 'typesafe-fetch';

// See below how to generate the API definitions
import { paths as ApiDefinition } from "./petstore";

const fetchFn: FetchFunction = (url, { method, body, headers }) => {
  // You can also use a global error handler by catching errors here
  // Or insert any additional custom headers

  // This is also where you can decide which fetch function to use, see
  // below for examples using other libraries
  return fetch(url, { method, body, headers }).then(res => res.json());
};

// Now set up using your existing OpenAPI definition
const safeFetch = getSafeFetch<ApiDefinition>({
  fetch: fetchFn,
});

// Make API calls :)
const res = safeFetch('/endpoint', {
  query: {
    sampleParam: 123,
  },
});

Using with multiple APIs

You can use union types to combine multiple APIs into one (assuming the endpoints are different and the base URL is the same, otherwise just use different instances of safeFetch)

import { paths as SomeApiDefinition } from "./some-api";
import { paths as SomeOtherApiDefinition } from "./some-other-api";

const safeFetch = getSafeFetch<SomeApiDefinition & SomeOtherApiDefinition>({
  fetch,
});

Generating the API definitions

This library relies on the TS models generated by OpenAPI-TypeScript

For the simplest way to generate the models run:

npx openapi-typescript https://petstore.swagger.io/v2/swagger.json --output petstore.schema.ts

Check out their docs for more advanced use-cases.

Fetch function

The library is setup by calling getSafeFetch<ApiDefinition>() with your ApiDefinition and an object containing an optional baseUrl and a mandatory fetch function.

This function has the following signature:

type FetchOptions = {
  method: string;
  body?: BodyInit;
  headers?: HeadersInit;
}

export type FetchFunction = (url: string, options: FetchOptions) => Promise<any>;

All you need is to pass a function that will send the request in any way, and return a Promise with the return data (not a Response object, you must extract it from there).

Using fetch as a fetch function

You can either use the browser's built-in fetch function, or any of the polyfills such as node-fetch, cross-fetch...

const fetchFn: FetchFunction = (url, { method, body, headers }) => 
  fetch(url, { method, body, headers }).then(res => res.json());

Using axios as a fetch function

You can either use the browser's built-in fetch function, or any of the polyfills such as node-fetch, cross-fetch...

const fetchFn: FetchFunction = (url, { method, body, headers }) => 
  axios({
    url,
    method,
    headers,
    data: body,
  }).then(res => res.data);