0.1.0 • Published 1 year ago

heast v0.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

heast

npm version npm downloads Github Actions Codecov

Small, type-safe, function wrapper for better error handling and input/output-validation with zod. Inspired by neverthrow.

Usage

Install package:

# npm
npm install heast

# yarn
yarn install heast

# pnpm
pnpm install heast

Import:

// ESM
import {} from "heast";

// CommonJS
const {} = require("heast");

Introduction

heast aims to be the default way to define a function in your project. It is a wrapper around a function that returns a Result object. The Result object is a type-safe way to handle errors. It is inspired by neverthrow, but written from scratch.

It also includes input + output validation using zod.

Examples

Ok and Err

const getName = defineFunction({
  output: z.string(),
  handler: ({ ok }) => ok("Jakob"),
});

const name = getName(); // Result containing "Jakob"

const failToGetName = defineFunction({
  output: z.string(),
  handler: ({ err }) => err("NOT_FOUND", "Could not find name"),
});

const nameError = failToGetName(); // Result containing an error with name "NOT_FOUND" and message "Could not find name"

As you can see, the handler function is called with an object containing the ok and err functions. These functions are used to return a Result object. The ok function returns a Result object with the value Jakob and the err function returns a Result object with the error Error.

Error map

const withErrorMap = defineFunction({
  input: z.number(),
  errors: {
    CANT_BE_ONE: "Number cannot be 1",
  },
  handler({ input, err, ok }) {
    if (input === 1) {
      return err("CANT_BE_ONE", "Number cannot be 1");
    }

    return ok();
  },
});

const withErrorMapResult = withErrorMap(1); // Result containing an error with name "CANT_BE_ONE" and message "Number cannot be 1"

The errors object is used to map error names to error messages. This is useful when you want to return a custom error message to the user. The error name is used to identify the error, while the error message is used to display the error to the user.

The error name is automatically inferred when calling err.

Async functions

const asyncFunction = defineFunction({
  input: z.number(),
  output: z.string(),
  async: true,
  handler: async ({ input, ok }) => {
    const result = await someAsyncFunction(input);

    return ok(result);
  },
});

Async functions work exactly the same as normal functions. The only difference is that the handler function is marked as async and async is set to true.

Match Results

const uncertainOutcome = defineFunction({
  output: z.string(),
  errors: {
    UNLUCKY: "You were unlucky",
  },
  handler: ({ ok, err }) => {
    let rand = Math.random();
    if (rand > 0.5) {
      return ok(`You were lucky! ${rand}`);
    }

    return err("UNLUCKY", "You were unlucky");
  },
});

const result = uncertainOutcome();
result.match({
  err: {
    UNLUCKY: (error) => {
      console.log(error);
    },
  },
  ok: (data) => {
    console.log(data);
  },
});