kneel
TypeScript icon, indicating that this package has built-in type declarations

0.1.8 • Public • Published

kneel

Fetch with zod.

Installation

npm install kneel

Usage

import kneel from 'kneel'
import { z } from 'zod'

const read = await kneel({
  url: 'http://localhost:3000',
  response: z.object({ names: z.array(z.string()) })
})
const uppercaseNames = read.names.map((name) => name.toUpperCase())

const write = await kneel({
  url: 'http://localhost:3000',
  request: z.object({ name: z.string() }),
  response: z.object({ count: z.number() }),
  body: { name: 'Zelda Fitzgerald' }
})
console.log(typeof write.count) // 'number'

Problem

Many requests require validation. Making it functional can require patterns like annotating with unknown.

Without kneel

import { z } from 'zod'

const outputSchema = z.objet({ output: z.number() })
type Output = z.infer<typeof schema>
async function read (): Promise<Output> {
  const response = await fetch('http://localhost:3000')
  // Don't use the unvalidated data
  const json: unknown = await response.json()
  return outputSchema.parse(json)
}

const inputSchema = z.object({ input: z.string() })
type Input = z.infer<typeof schema>
async function write (input: Input): Promise<Output> {
  const body = inputSchema.parse(input)
  const response = await fetch('http://localhost:3000', {
    method: 'POST',
    body: JSON.stringify(body)
  })
  const json: unknown = await response.json()
  return outputSchema.parse(json)
}

Solution

kneel requires a zod schema for the response. It also requires a schema if you include a body.

With kneel

import kneel from 'kneel'
import { z } from 'zod'

const outputSchema = z.object({ output: z.number() })
type Output = z.infer<typeof outputSchema>
async function read (input: Input): Promise<Output> {
  return kneel({
    url: 'http://localhost:3000',
    response: outputSchema,
  })
}

const inputSchema = z.object({ input: z.string() })
type Input = z.infer<typeof inputSchema>
async function write (input: Input): Promise<Output> {
  return kneel({
    url: 'http://localhost:3000',
    response: outputSchema,
    body: input,
    request: inputSchema,
  })
}

kneel takes a single object with two required parameters:

  • url, a string
  • response, a zod schema for the response payload

You can optionally set:

  • method, a string
  • headers, matching the native fetch headers

You can optionally include a request payload with:

  • request, a zod schema
  • body, a value matching the request schema

The body will be parsed by the request schema. By default including a body sets the method to 'POST'.

By default the request body will be encoded with JSON.stringify() and the Content-Type header will be set to application/json. You can override this with:

  • encoding, which must be either 'application/x-www-form-urlencoded', 'multipart/form-data', 'text/plain', or 'application/json'.
const inputSchema = z.object({ input: z.string() })
type Input = z.infer<typeof inputSchema>
async function write (input: Input): Promise<Output> {
  return kneel({
    url: 'http://localhost:3000',
    response: outputSchema,
    body: input,
    request: inputSchema,
    encoding: 'application/x-www-form-urlencoded'
  })
}

The encoding becomes the value of the Content-Type header. application/x-www-form-urlencoded uses new URLSearchParams() to encode the body. multipart/form-data uses new FormData(). text/plain uses String().

kneel returns a promise that resolves to the parsed response payload.

Dependencies (1)

Dev Dependencies (3)

Package Sidebar

Install

npm i kneel

Weekly Downloads

6

Version

0.1.8

License

Unlicense

Unpacked Size

23.5 kB

Total Files

8

Last publish

Collaborators

  • davidystephenson