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

zod-endpoints

v0.1.7

Published

Typescript contract first strictly typed endpoints

Downloads

425

Readme

Zod-endpoints

Contract first strictly typed endpoints. By defining endpoints as a zod schema, all the requests and responses can be checked and parsed at runtime. Moreover, the TypeScript compiler can check the in- and output types of the endpoints.

In this way the problem space of your application will become much smaller to begin with. By using zod-endpoints you can rely on the types during development and on validation at runtime. This yields reqests and responses you can trust. The focus can shift more to defining business logic instead of input validation and error handling.

The schema can be used as a contract between consumer and producer. Drivers can be generated from the contract which ensures proper communication between a client and server.

Simplified model

Zod-endpoints is based on a type representation of a http schema. Below a simplyfied version of the model. The full model can be found here. The model is a union of requests which contains a union of response objects. Both request and response contain a union of body types.

type Body = {
    type: "applictions/json" | "plain/html"
    content: any
}

type Reqest = {
    method: "GET" | "POST" | "PUT" | "DELETE"
    path: [...string[]]
    body: Body | ...Body
}

type Response = {
    status: number
    body: Body | ...Body
}

type Http = Reqest & {
    responses: Response | ...Response
}

type Schema = Http | ...Http

Getting started

First step is to define an endpoint by making use of the zod-endpoints dsl. Below you can find an example of a simple example. This example contains two endpoints to get and create a project.

Define endpoints

import * as z from "zod-endpoints";

const project = z.object({
  id: z.string().uuid(),
  name: z.string(),
})

const schema = z.endpoints([
  z.endpoint({
    name: "GET_PROJECT",
    method: "GET",
    path: [z.literal("projects"), z.string().uuid()],
    responses: [
      z.response({
        status: 200,
        body:{
          type: "application/json",
          content: project
        }       
      }),
    ],
  }),
  z.endpoint({
    name: "CREATE_PROJECT",
    method: "POST",
    path: [z.literal("projects")],
    body:{
      type: "application/json",
      content: project
    },
    responses: [
      z.response({
        status: 201,  
      }),
    ],
  }),
]);

Api

The endpoints can be convert into a service or a client with the Api type.

Server

For the type transforms the schema into an object of the requests. The key of the object is the name of the route the value is a function from the request to a union of the responses. This object is strict typed and exhaustive.

const service = {
  findProjectById: (id:string):Project => {},
  createProject: (project:Project) => {},
}
import * as z from "zod-endpoints";

const server: z.Api<typeof schema> = {
  "GET_PROJECT": ({path}) => findProjectById(path[1]).then(project => ({ 
    status: 200, 
    body:{
      type: "application/json", 
      content:project
    }
  })),
  "CREATE_PROJECT": ({body}) => createProject(body).Promise.resolve({ 
    status: 201 
  }),
};

Client

The client implementation

const http = (req: z.ApiRequest) => {
    fetch(req.path.join('/'), {
      method: req.method
    })
}
import * as z from "zod-endpoints";

const client: z.Api<typeof schema> = {
  "GET_PROJECT": (req) => http(req),
  "CREATE_PROJECT": (req) => http(req)
};

Documentation

Zod endpoints is fully compatible with open api specification. The schema can be transformed into open api json. For example with Swagger this can be presented as a documentation website.

const docs = z.openApi(schema)

GitHub Logo