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

js-checker

v1.0.11

Published

a type checker for javascript

Downloads

18

Readme

js-checker

  • js-checker is a javascript type checker.
  • It can automatically generate interface documentation.

Installation

# install js-checker
npm install js-checker
 
# run test
npm run test

# get demo .html file
npm run html

Example

let {c, t, renderHtml, getHtml} = require('js-checker');

let personType = c.Obj({
    age: t.Num,
    nick: t.Num,
    favourites: c.Arr(t.Str),
    details: c.Optional(t.Any)
});

//generate interface documentation
getHtml(personType.show, './test.html');


//return {age: 16, nick: 'zhangsan', favourites: ['game', 'running']}.
personType({
    age: 16,
    nick: 'zhangsan',
    favourites: ['game', 'running']
});

//return a Error, because favourites is not an Array.
personType({
    age: 16,
    nick: 'zhangsan',
    favourites: 'game'
});

//return a Error, because favourites is not in the object.
personType({
    age: 16,
    nick: 'zhangsan',
    details: 'anything'
});

API

let {c, t, renderHtml, getHtml} = require('js-checker');

t

t defined some basic data types, each data type is a function to check and convert the input data. If the input data meets the defined data type, it will return a converted data, else it will throw a Error with description message.

  • t.Null: the input data is null or undefined

  • t.Any: the input data is not null and not undefined

  • t.Num: the input data is a Number or can be converted to a Number

  • t.Str: the input data is a String or can be converted to a String

  • t.Fn: the input data is a function

  • t.Json: the input data is an Array or an Object

  • t.Arr: the input data is an Array

  • t.Obj: the input data is an Object

  • t.Bool: the input data is true/false/"true"/"false"

  • t.Date: the input data can be converted to a Date by using new Date()

c

c defined some combined data type generators,it can generate a new type like "t" from the basic data types and combined data types.

  • c.Val(value): the input data must be equal to the given value.
let type = c.Val('hello world');
// return 'hello world';
type('hello world');

// return an Error("helloworld is not eq to hello world")
type('helloworld')
  • c.OrVal(valueArr): the input data must be one of the given values in valueArr.

let type = c.OrVal('hello world', 'helloworld');
// return 'hello world';
type('hello world');

// return helloworld
type('helloworld')

// return an Error("hello-world is not eq to hello world and hello-world is not eq to helloworld")
type('hello-world')
  • c.Obj({key1: type1, key2: type2...}}): the input data must be a Object and the value of each key must meet the type.

let type = c.Obj({
    age: t.Num,
    nick: t.Str
});

// return {age: 13, nick: "Lucy"};
type({age: 13, nick: 'Lucy'});

// return {age: 13, nick: "Lucy"}, home is ignored;
type({age: "13", nick: 'Lucy', home: 'hangzhou'});

// return an Error(age is not a Number)
type({age: "Lucy", nick: 'Lucy'});

// return an Error(age is undefined)
type({nick: 'Lucy'});
  • c.Arr(type): the input data must be an Array and every value of the Array must meet the type.

let type = c.Arr(c.Obj({
    age: t.Num,
    nick: t.Str
}));

// return [{age: 13, nick: 'Lucy'}, {age: 14, nick: 'Linlin'}]
type([{age: 13, nick: 'Lucy'}, {age: 14, nick: 'Linlin'}]);

// return an Error(1 -> age -> is not a Number)
type([{age: 13, nick: 'Lucy'}, {age: "13x", nick: 'Linlin'}]);
  • c.Or(type1, type2...): the input data must meet one of the types(type1, type2...)
let type = c.Or(
    t.Num, 
    c.Obj({age: t.Num})
)

// return 13
type(13);

// return {age: 13}
type({age: 13})

// return an Error(is not a Number and is not an Object)
type('hello')
  • c.Optional(type): the input data is Optional, generally used in c.Obj

let type = c.Obj({
    age: t.Num,
    nick: c.Optional(t.Str)
});

// it will return {age: 13}
type({age: 13})
  • c.Default(type, defaultValue): if the input data is undefined, it will give a defaultValue, generally used in c.Obj
let type = c.Obj({
    age: t.Num,
    nick: c.Default(t.Str, 'zhangsan')
});

// it will return {age: 13, nick: 'zhangsan'}
type({age: 13})

// it will return {age: 13, nick: 'lisi'}
type({age: 13, nick: 'lisi'})
  • c.Map(keyType, valueType): if the input data is a Object, the key of the Object must meet the keyType and the value of the Object must meet the valueType.
let type = c.Map(t.Str, t.Obj);

// return an Error("the value of a is not a Object")
type({'a': 1, 'b': {'c': 2})
  • c.Extend(type1, type2...): the type1, type2... must return a Object, it will return a new c.Obj like Object.assign(type1, type2...)

let type = c.Extend(
    c.Obj({
        age: t.Num
    }),
    c.Or(
        c.Obj({
            type: c.Val('Student'),
            school: t.Str
        }),
        c.Obj({
            type: c.Val('Worker'),
            workplace: t.Str
        })
    )
);

// return {age: 13, type: 'Student', school: 'hangzhou'}
type({age: 13, type: 'Student', school: 'hangzhou'});

// return {age: 13, type: 'Student', workplace: 'hospital'}
type({age: 13, type: 'Worker', workplace: 'hospital'});

// return an Error(type is not eq to "Student" and workplace is Null)
type({age: 13, type: 'Worker', school: 'hangzhou'})
  • c.Fn({input: [type1, type2...]}, output: type): Check the input and output of the function

let type = c.Fn({
    input: [t.Num, t.Str],
    output: c.Obj({
        a: t.Num,
        b: t.Str
    })
});

let fn = function(age, nick){
    return {
        a: age,
        b: nick
    };
};
// return {a: 13, b: 'Lucy'}
type(fn)(12, 'Lucy');

// return an Error("The 0th parameter of the function ==> is not a Num")
type(fn)('Lucy', 'Lucy');
  • c.Str(constStr): the input is a String and must equal to the constStr.
let type = c.Str('hello world');

// return 'hello world';
type('hello world');

// return an Error("is not eq to hello world")
type('hello-world');
  • c.OrStr(constStr1, constStr2...): the input is a String must be one of the input constStr1, constStr2...
let type = c.OrStr('hello world', 'helloWorld');

// return 'hello world';
type('hello world');

// return 'helloWorld';
type('helloWorld');

// return an Error("is not eq to hello world")
type('hello-world');
  • c.Num(constNum): the input is a Number and must equal to the constNum.
let type = c.Num(1);

// return 1;
type(1);

// return an Error("is not eq to 1")
type('hello-world');
  • c.OrNum(constNum1, constNum2...): the input is a Number and must be one of the input constNum1, constNum2...
let type = c.OrNum(1, 2);

// return 1;
type(1);

// return 2;
type(2);

// return an Error("is not eq to 1 and is not eq to 2")
type('hello-world');
  • c.TagOr([type1, type2, type3...], [tag1, tag2...]): 'c.TagOr' is the strict mode of 'c.Or'. Tags in order to distinguish the matching rules of each branch of 'c.TagOr'. The tag definition for each branch cannot be repeated.
let type = c.TagOr(
    [
        c.Obj({
            A: c.Str('a1'),
            B: c.Str('b1'),
            value: t.Num
        }),
        c.Obj({
            A: c.Str('a2'),
            B: c.Str('b2'),
            age: t.Num
        })
    ],
    ['A', 'B']
);

// return {A: 'a1', B: 'b1', value: 1};
type({A: 'a1', B: 'b1', value: 1});

// return an Error("value ==> is not a Num"), it direct match to the first branch;
type({A: 'a1', B: 'b1'});

// return an Error("Tag definition<A,B> does not satisfy: a1-b1/a2-b2"), Directly tell you that the tag input is incorrect
type({A1: 'a1', A2: 'b1'});
  • c.Custom(fn): The type can be dynamically generated by function. Based on this we can implement recursive definition of type checking.
let type = c.Custom(
    () => {
        return c.Obj({
            age: t.Num,
            nick: t.Str,
            next: c.Optional(type)
        })
    }
);

// return {age: 13, nick: 'zhangsan', next: {age: 12, nick: 'lisi'}};
type({age: 13, nick: 'zhangsan', next: {age: 12, nick: 'lisi'}});

add comment/description for the type

You can add "D" to the beginning of the above defined basic data types and combined data types function name, then you can add the comment for the type definition. The comment can help produce a more detailed documentation description.

  • t.DNull, t.DAny, t.DNum, t.DStr, r.DFn, t.DJson, t.DObj, t.DArr, t.DBool, t.DDate
  • c.DVal, c.DOr, c.DOptional, c.DDefault, c.DArr, c.DObj, c.DOrVal, c.DMap, c.DExtend
let type = c.DObj('student information')({
    age: c.DDefault('age of the student, default 13')(t.Num, 13),
    nick: t.DStr('nick of the student')
});

type.show

Each data type defined above will have a "show" attribute, you can get a more detailed description of the data type and use it generate a data type document description.

let type = c.DObj('student information')({
    age: c.DDefault('age of the student, default 13')(t.Num, 13),
    nick: t.DStr('nick of the student')
});

console.log(type.show);

=>


{
  "name": "Obj",
  "attribute": {
    "age": {
      "name": "Default",
      "attribute": [
        {
          "name": "Num"
        },
        13
      ],
      "description": "age of the student, default 13"
    },
    "nick": {
      "name": "Str",
      "description": "nick of the student"
    }
  },
  "description": "student information"
}

renderHtml

you can use renderHtml function to get a html string about the detailed description of the type from type.show.


renderHtml(type.show);

getHtml

you can also use getHtml function to get a ".html" file about the detailed description of the type from type.show.


let type = c.DObj('测试')({
    id: t.DNum('自增id'),
    name: t.DStr('名称'),
    details: c.DObj('详情')({
        id: t.Str,
        name: t.Num
    })
});
getHtml(type.show, './test.html');

=>

detailed document