Skip to content

jeengbe/vality

Repository files navigation

Vality

A TypeScript schema descriptor library with zero dependencies.

See https://jeengbe.github.io/vality for more information.

License Version Coverage Status Dependencies

Vality is the heart of this repository. It is a declarative schema description library with the most intuitive syntax and allows for validation and transformation of data. Then extract the types from your schema for 100% type safety. And all with 0 runtime dependencies.

Find all of this and much more on https://jeengbe.github.io/vality/vality.

import { v, Parse } from "vality";

const Person = {
  name: v.string,
  age: v.number({ min: 6 }),
  email: v.email,
  referral: ["friends", "ad", "media", null],
  languages: [["de", "en", "fr", "se"]],
} as const;

type Person = Parse<typeof Person>;
/* {
  name: string;
  age: number;
  email: Email;
  referral: "friends" | "ad" | "media" | null;
  languages: ("de" | "en" | "fr" | "se")[];
} */

Now that I have your attention, head over to https://jeengbe.github.io/vality/vality to find out what's going on here. You won't regret it ;) Or check out packages/vality.

Or continue scrolling down to see what else is in this repository.

License Version Coverage Status

const Brand = {
  logo: v.dict([64, 128, 256], v.url),
};

type Brand = Parse<typeof Brand>;
/* {
  logo: {
    [x: number]: URL; // Where are the literal values???
  };
} */

Can you spot what's wrong with this model? Correct, it's missing the literal types for the keys. This is a common mistake when using Array or Enum Shorts and can be easily fixed by adding as const. (Find more information on this mistake here).

const Brand = {
  logo: v.dict([64, 128, 256] as const, v.url),
};

type Brand = Parse<typeof Brand>;
/* {
  logo: {
    64: URL;
    128: URL;
    256: URL;
  };
} */

Forgetting this sucks and can quickly become a source of frustration when suddenly types are weird. ESLint to the rescue! It will warn you when you forget to add as const in places where is may backfire and adds it automatically for you.

Find more information on https://jeengbe.github.io/vality/eslint-plugin-vality or check out packages/eslint-plugin-vality.

License Version Coverage Status

Use Vality to describe your configuration and load+validate it.

import { v } from "vality";
import { loadEnv } from "vality-env";

const config = {
  jwt: {
    privateKey: v.string,
  },
  db: {
    url: v.env("DATABASE_URL", v.string),
    databaseName: v.env("DATABASE_NAME", v.string({
      default: "service"
    })),
  },
};

export function loadConfig() {
  const validatedConfig = loadEnv(config);

  if (!validatedConfig.valid) {
    console.error(validatedConfig.errors);
    throw new Error('Invalid config');
  }

  return validatedConfig.data;
}
DATABASE_URL=http://localhost:8259
# DATABASE_NAME=
JWT_PRIVATE_KEY=asdasdasdasd