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

prover-ts

v1.2.1

Published

Prover-ts is a small lightweight package to parse through unknown shapes, providing strong typing.

Downloads

11

Readme

Prover-ts

Prover-ts is a small lightweight package to parse through unknown shapes, providing strong typing.

Installation

npm install prover-ts

Usage

import { prover } from "prover-ts";

/*
 * API returns an object. A familiar shape is known, but strong confirmation is needed.
 * Prover-ts can help on that.
 */

try {
  const unknownShape = await fetchingSomething(); // unknown

  const parsedShape = prover
    .object({ name: prover.string(), lastName: prover.string(), age: prover.number() })
    .parse(unknownShape);
} catch (error) {
  console.log(error);
}

parsedShape would be typed like this:

const parsedShape: {
  name: string;
  lastName: string;
  age: number;
};

prover-ts would return an error if the object did not match the expected shape. Future releases might change this.

Supported types

  • String

    • nonEmpty

      • expects a non-empty string.

        const result = prover.string().nonEmpty().parse("Test");
        
        // Throws
        prover.string().nonEmpty().parse("");
    • max

      • Parameters

        maxLength {number} expected max characters

        const result = prover.string().max(5).parse("Hello");
        
        // Throws
        prover.string().max(5).parse("Hello World");
    • min

      • Parameters

        minLength {number} expected min characters

        const result = prover.string().min(5).parse("Hello");
        
        // Throws
        prover.string().min(5).parse("Hi");
    • length

      • Parameters

        length {number} expected string length

        const result = prover.string().length(5).parse("Hello");
        
        // Throws
        prover.string().length(5).parse("Hello again");
    • includes

      • Parameters

        toInclude {string} expected string to be present

        const result = prover.string().includes("Hello").parse("Hello World");
        
        // Throws
        prover.string().includes("Hello").parse("Hi World");
    • startsWith

      • Parameters

        toStartWith {string} expected characters matching the beginning of the string

        const result = prover.startsWith("Hello").parse("Hello, world!");
        
        // Throws
        prover.startsWith("Hello").parse("Hi, world!");
    • endsWith

      • Parameters

        endsWith {string} expected characters matching the end of the string

        const result = prover.endsWith("world!").parse("Hello, world!");
        
        // Throws
        prover.endsWith("world!").parse("Hello, universe!");
    • regex

      • Parameters

        pattern {string | RegExp} pattern to match

        const result = prover.regex(/^\d{4}$/).parse("1234");
        
        // Throws
        prover.regex(/^\d{4}$/).parse("12345");
    • email

      • expects an email

        const result = prover.email().parse("[email protected]");
        
        // Throws
        prover.email().parse("invalid-email");
    • date

      • expects a date formatted yyyy-mm-dd

        const result = prover.date().parse("2023-05-30");
        
        // Throws
        prover.date().parse("30/05/2023");

        future implementation might support different formats

    • numeric

      • expects a numeric string

        const result = prover.numeric().parse("12345");
        
        // Throws
        prover.numeric().parse("abc12345");
    • alphanumeric

      • expects an alphanumeric string

        const result = prover.alphanumeric().parse("abc123");
        
        // Throws
        prover.alphanumeric().parse("abc@123");
    • ipv4

      • expects an ipv4 matching string

        const result = prover.ipv4().parse("192.168.0.1");
        
        // Throws
        prover.ipv4().parse("256.256.256.256");
    • func

      • Parameters

        predicate {(arg: string) => boolean} predicate function responsible to validate string

        const isUpperCase = (arg: string) => arg === arg.toUpperCase();
        const result = prover.func(isUpperCase).parse("HELLO");
        
        // Throws
        prover.func(isUpperCase).parse("Hello");
  • Number

    • positive

      • expects a positive number.

        const result = prover.number().positive().parse(1);
        
        // Throws
        prover.number().positive().parse(-1);
    • negative

      • expects a negative number.

        const result = prover.number().negative().parse(-1);
        
        // Throws
        prover.number().negative().parse(1);
    • equal

      • toEqual {number} expects an equal number.

        const result = prover.number().equal(42).parse(42);
        
        // Throws
        prover.number().equal(42).parse(-1);
    • gt

      • Parameters

        comp {number} number to be greater than

        const result = prover.number().gt(42).parse(69);
        
        // Throws
        prover.number().gt(42).parse(22);
    • gte

      • Parameters

        comp {number} number to be greater or equal than

        const result = prover.number().gte(42).parse(42);
        
        // Throws
        prover.number().gte(42).parse(24);
    • lt

      • Parameters

        comp {number} number to be lesser than

        const result = prover.number().lt(42).parse(24);
        
        // Throws
        prover.number().lt(42).parse(69);
    • lte

      • Parameters

        comp {number} number to be lesser or equal to

        const result = prover.number().lte(42).parse(42);
        
        // Throws
        prover.number().lte(42).parse(69);
    • multiple

      • Parameters

        comp {number} number to be multiple of

        const result = prover.number().multiple(5).parse(10);
        
        // Throws
        prover.number().multiple(3).parse(10);
    • save

      • Requires number to be a safe integer, meaning, between Number.MIN_SAFE_INTEGER and Number.MAX_SAFE_INTEGER

        const result = prover.number().save().parse(10);
        
        // Throws
        prover.number().save().parse(Infinity);
    • finite

      • Requires number to be in between Infinity and -Infinity

        const result = prover.number().finite().parse(69);
        
        // Throws
        prover.number().finite().parse(Infinity);
    • func

      • Parameters

        func {(arg: number) => boolean} predicate function responsible to validate number

        const isEven = (arg) => arg % 2 === 0;
        
        const result = prover.number().func(isEven).parse(10);
        
        // Throws
        prover.number().func(isEven).parse(3);
  • Object

    • safe

      • filters out unexpected properties

        const result = prover
          .object({ name: prover.string().nonEmpty(), age: prover.number().positive() })
          .safe()
          .parse({ name: "John", age: 30, address: ["street 1", "street 2"] });

        Without calling safe(), result object would have a address property, since prover's default behavior would NOT filter out a property that was not expected to exist.

    • Other examples

      • const result = prover
          .object({ name: prover.string().nonEmpty(), age: prover.number().positive() })
          .parse({ name: "John", age: 30 });
      • const result = prover
          .object({
            name: prover.string().nonEmpty(),
            idNumber: prover.number().positive(),
            married: prover.boolean(),
            address: prover.array(prover.string()),
          })
          .parse({ name: "John", idNumber: 12131313, married: true, address: ["hollywood, beverly hills"] });

        Inferred correctly

        const result: { name: string; idNumber: number; married: boolean; address: string[] };
  • Record

    When you only care about the values and their types

    • Examples

      • const result = prover.record(prover.string()).parse({ name: "John", lastName: "Doe" });
        
        // Throws
        prover.record(prover.string()).parse({ name: "John", age: 30 });
  • Array

    • max

      • Parameters {nElements} number of max elements that should be inside the array

        const result = prover.array([prover.number()]).max(10).parse([1, 2, 3, 4, 5, 6]);
        
        // Throws
        prover.array([prover.number()]).max(2).parse([1, 2, 3, 4, 5, 6]);
    • min

      • Parameters {nElements} number of min elements that should be inside the array

        const result = prover.array([prover.number()]).min(2).parse([1, 2, 3, 4, 5, 6]);
        
        // Throws
        prover.array([prover.number()]).min(10).parse([1, 2, 3, 4, 5, 6]);
    • size

      • Parameters {nElements} number of exact elements that should be inside the array

        const result = prover.array([prover.number()]).size(6).parse([1, 2, 3, 4, 5, 6]);
        
        // Throws
        prover.array([prover.number()]).size(10).parse([1, 2, 3, 4, 5, 6]);
    • nonEmpty

      const result = prover.array([prover.number()]).nonEmpty().parse([1, 2, 3, 4, 5, 6]);
      
      // Throws
      prover.array([prover.number()]).nonEmpty().parse([]);
    • Other Examples

      const result = prover.array([prover.number(), prover.string()]).parse([1, 2, "3", 4, "5", 6]);
      
      // Throws
      prover.array([prover.number(), prover.string()]).parse([1, 2, "3", 4, "5", 6, true]);

      Inferred correctly

      const result: (string | number)[];
  • Tuple

    • Examples

      • prover.tuple([prover.number(), prover.number(), prover.boolean()]).parse([1, 2, true]);
        
        // Throws
        prover.tuple([prover.number(), prover.number(), prover.boolean()]).parse([1, "2", true]);

Record and Tuple are still experimental features.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

Make sure to include changeset.

License

MIT