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

klar

v1.0.5

Published

A tool to infer and generate static type definitions of resources returned by backend APIs.

Downloads

13

Readme

klar

klar reads responses from backend endpoints and generates strongly typed interface definitions that clearly describe the data returned. It outputs GraphQL Schemas, TypeScript Definitions, and flow types.

Klar Demo

klar returns interfaces whose members are always scalar values. If a member is a nested object, it continues to recursively define interfaces until final scalar values are available.

It could be extended to also just describe any old POJSO.

Motivation

Developer experience is something that is important to me. Developer convenience is something I enjoy. I'd like to, just before yarn starting a web application that interacts with some type of backend, fetch the latest, greatest resource type definitions for my project, and then take full advantage of my editor's incredible intellisense, allowing me to have on-demand autocomplete for the data I'm working with.

Getting Started

To get started with klar, you'd need to tell it where your data lives. To do this, you'd need to create a config file. I know zero-config is currently sexy, but this is information that we have no way of inferring.

A klar.config.js is a file that points klar in the right direction. Consider,

module.exports = {
  url: "https://jsonplaceholder.typicode.com",
  resources: {
    Post: "/posts",
    Comment: "/comments",
    Album: "/albums",
    Photo: "/photos",
    Todo: "/todos",
    User: "/users",
  },
};

As soon as your config file is in place, simply npx klar in your project, and you'll magically have interface definitions. Alternatively, yarn add klar -D will add it as a dependency in your project so it can be attached to a prestart script or similar.

Config File

klar.config.js is a barebones file that points klar in the right direction. It does so by giving klar a URL against which to send requests, and a map of resource names and their respective paths as we've already seen in the previous example.

A full illustration of the config options available to you in this file is below.

module.exports = {
  url: "https://jsonplaceholder.typicode.com",

  /**
   * A function that is applied to the immediately
   * returned data.
   */

  resolve: data => data.iOnlyWantThisKey,

  resources: {
    Post: "/posts",

    // You can also specify resource-level resolvers,
    Comment: { path: "/comments", resolve: data => data.comment },
    Album: "/albums",
    Photo: "/photos",
    Todo: "/todos",
    User: "/users",
  },

  /**
   * Request options that follow the Init spec
   * of the fetch API: https://developer.mozilla.org/en-US/docs/Web/API/Request/Request
   */
  request: {
    // headers, credentials, etc. go in here.
  },
};

CLI Configuration

As a CLI tool, klar supports the following configuration options:

--configFile, -c

Path to an alternative config file instead of klar.config.js that implements an identical exported schema.

--outDir, -o

This option specifies an output folder for your definition files. Current working directory by default.

--dataProp, -d

Usually in the GraphQL world, but also quite common: data sometimes lives in a data property in a returned response. When this flag is set, it simply unwraps the response and defines interfaces based on the shape of response.data.

--graphql, -g

Output GraphQL schema definitions instead of TypeScript files. 🔥

--flow, -f

Output Flow type definitions instead of TypeScript files.

--prefix, -p

This option will prefix interface names with the name of the resource defined in the config file. Consider,

// klar.config.js
{
  resources: {
    Bae: '/wolf',
  }
}

// in terminal,
klar -p

// Bae.d.ts
interface Bae {
  name: string
  otherNestedProperty: BaeOtherNestedProperty
}

interface BaeOtherNestedProperty {
  like: boolean
}

Without the prefix option, otherNestedProperty's interface definition would have been un- prefixed: OtherNestedProperty. This namespacing helps multiple exported interfaces with identical identifiers.

Why klar?

klar is the German word for "clear". I chose to call this project klar because it makes resource types (or object shapes) fairly clear.

Typically, in German culture, when a type of contract is formed, it's usually agreed upon with the phrase "Alles klar", or "all clear".

I like how the metaphor applies to this use case of clear communication between client and server.

Next Steps

While this tool has already helped me quite a lot, there is room for improvement! Below is a summary of how it can be improved, and areas wherein you can get involved!

  1. Cover klar with tests for what can be tested.
  2. Find a comfortable way to handle authenticated requests.
  3. Find a comfortable way to request specific resources without requiring specific IDs: currently, the resource map from the config file expects a path to a resource with a specific ID, which it fetches and whose type information it infers. It would be interesting to see how we proceed when specific IDs are unknown.

Contributing

Start with an issue. Let's discuss the issue, and then one of us will submit a pull request.