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

typed-api-call

v0.1.3

Published

Effortlessly construct dynamic text by seamlessly integrating variables into your phrases

Downloads

4

Readme

typed-api-call

Typesafe api call generator. Make your external api call safer and easier

Installation

npm install typed-api-call

Introduction

This library is a wrapper around the fetch api. It allows you to define your api calls and their schemas. It will then generate a function that will make the api call for you and return the response with the right type.

It's typesafe, so you can't make a mistake in your api call definition or in the api call itself. It will also check the response of your api call and throw an error if it doesn't match the schema.

Currently, it only supports zod for the schemas, but it will be possible to use other libraries in the future.

If you have any suggestion or question, feel free to open an issue.

Usage

import { createApiCall } from 'typed-api-call';
import { z } from 'zod';

export const getHeaders = ({ token }: { token?: string }) => {
  const headers = new Headers();
  headers.append('Accept', 'application/json');
  headers.append('Content-Type', 'application/json');
  if (token) {
    headers.append('Authorization', `Bearer ${token}`);
  }
  return headers;
};

const myApiCall = createApiCall({ url: 'https://my-api.com/', getHeaders });

// GET https://my-api.com/users

const userSchema = z.object({
  id: z.string(),
  name: z.string(),
  email: z.string(),
});

const getusers = myApiCall({
  url: 'users',
  method: 'GET',
  input: z.object({ email: z.array(z.string().email()) }),
  response: z.object({ data: z.array(userSchema) }),
});

const users = await getusers({ params: undefined, data: { email: ['[email protected]'] } });

// Patch https://my-api.com/users/${userId}

const patchUser = myApiCall({
  url: 'users/${userId}',
  method: 'PATCH',
  params: z.object({ userId: z.string() }),
  input: userSchema,
  response: userSchema,
});

// Be careful, you must provide the same params name in the url and in the params

Api

createApiCall

const myApiCall = createApiCall({ url: 'https://my-api.com/', getHeaders });
  • url: The base url of your api
  • getHeaders: A function that return the headers of your api call

If getHeaders has parameters, you can pass them to the api call like this:

In the api call definition:

const patchUser = myApiCall({
  url: 'users/${userId}',
  method: 'PATCH',
  ...

  headers: { token } // token is a parameter of getHeaders and will be passed to it
});

Or in the api call itself:

const users = await getusers({
  params: { userId: 'xxx' },
  data: { email: ['[email protected]'] },
  headers: { token },
});

ApiCall definition

const getuser = myApiCall({
  url: 'users/${userId}',
  method: 'GET',
  headers: { token },
  input: z.object({ email: z.array(z.string().email()) }),
  response: z.object({ data: z.array(userSchema) }),
  params: z.object({ userId: z.string() }),
});
  • url: The url of your api call. You can use ${paramName} to use a parameter in the url
  • method: The method of your api call
  • headers: The headers of your api call if you need to override the default headers
  • input: The schema of the data you send to your api call
  • response: The schema of the data you receive from your api call
  • params: The schema of the parameters you pass to your api call, if you use ${paramName} in the url

Api call

const users = await getusers({
  params: { userId: 'xxx' },
  data: { email: ['[email protected]'] },
  headers: { token },
});
  • params: The parameters of your api call if you use ${paramName} in the url
  • data: The data you send to your api call
  • headers: The headers of your api call if you need to override the default headers

On error handling

If the response of your api call doesn't match the schema, an error will be thrown. You can catch it by passing an onError function to your api call.

const getusers = myApiCall({
  url: 'users',
  method: 'GET',
  input: z.object({ email: z.array(z.string().email()) }),
  response: z.object({ data: z.array(userSchema) }),
  onError: (error, url) => {
    // error is the error thrown by zod or by the fetch api
    // url is the url of the api call
  },
});

You can also set a global onError function when you create your api call.

const myApiCall = createApiCall({ url: 'https://my-api.com/', getHeaders, onError });