InferJS-Library: Overview

InferJS-Library allows you to easily add runtime type checking by utilizing JSDoc multi-line comments in both client and server side JavaScript. The library is part of a bigger project named InferJS.

InferJS is provided with an InferJS-Compiler. The compiler interprets your JSDoc comments from your source code and compiles them into an InferObject file, that you can import into any JavaScript file.

With this library, you can also enable extended type checking and narrow down your data types with @infer expectation rules. Check out the examples below, to see how InferJS can save you time and money from costly bugs through development and release.

Built With

InferJS-Library: Installation

To install the latest version v of InferJS-Library locally with npm:

Install: Locally

npm install inferjs-library --save

Install: Globally

npm install -g inferjs-library

Optional: If you would like to download the repo source code with git:

git clone https://github.com/Codevendor/inferjs-library.git

InferJS-Library: Browser Version Instructions

If you would like to use the InferJS-Library from the browser, please select a precompiled/minified version and module type from the dist folder. There are 3 types of modules supported (esmodule, commonjs, script). The latest folder contains the latest version of the library.

Optional: Compiling the Latest Version of InferJS-Library

If you are missing the dist folder or would like to compile the latest version, follow the steps below.

Install Webpack

To build yourself, you will need to install Webpack version 5+ with the following commands. The commands need to be run from where the package.json is located. Or you can install them globally with the -g identifier.

Webpack Latest Install

// Local Install
npm install --save-dev webpack
npm install --save-dev webpack-cli

or

// Global Install
npm install -g --save-dev webpack
npm install -g --save-dev webpack-cli

The latest version of webpack 5+ automatically installs the terser-webpack-plugin with it. If it doesn't, you will need to install it as well, from where the package.json is located. The Terser plugin is used for minimizing/compressing the library code for use in the browser.

Optional: Terser Webpack Plugin

  • Required if webpack 4-
npm install terser-webpack-plugin --save-dev

After the node modules under devDependencies are installed, you can run the build process from where the package.json is located.

npm run build

InferJS-Library: Compiling InferObject Files

In order to use the InferJS-Library, you will need to compile an InferObject with the InferJS-Compiler. For more information on installing the InferJS-Compiler and its usage: click here.

InferJS-Library: Usage

Below are examples for using InferJS-Library in your code.

Browser: Usage Instructions

Copy one of the minimized inferjs-{version}.min.js from the dist folder to your website. Copy the pre-compiled InferObject file to your website, that was created with the InferJS-Compiler.

Add both to your webpage for type checking. You only need to recompile with the InferJS-Compiler, if you change your JSDoc multi-line comments, @param, @type, @inferid or @infer tags.

Browser ESModule: Import Example - Client side

<script type="module">
  import { InferObject } from "./inferobject.js";
  import { InferJS } from "./esmodule/inferjs-{version}.min.js";
  const inferjs = new InferJS(InferObject);
</script>

Browser JavaScript: Script Tag Sync Example - Client Side

<script src="./inferobject.js"></script>
<script src="./script/inferjs-{version}.min.js"></script>
<script>
  const inferjs = new InferJS(InferObject);
</script>

Node.js ESModule: Import - Server Side

import { InferObject } from "./inferobject.js";
import { InferJS } from "./esmodule/inferjs-{version}.min.js";
const inferjs = new InferJS(InferObject);

Node.js CommonJS: Require - Server Side

const InferObject = require("./inferobject.js");
const InferJS = require("./commonjs/inferjs-{version}.min.js");
const inferjs = new InferJS(InferObject);

There are many ways to utilize the InferJS-Library. The example above, imports in the pre-compiled InferObject file that was created with the InferJS-Compiler. Intialize the InferJS-Library class with the InferObject file you want to use.

// Intialize through constructor
const inferjs = new InferJS(InferObject);
    
// or intialize through property
const inferjs = new InferJS();
inferjs.inferObject = InferObject;

Once the InferJS-Library and InferObject file are included at the top of your file, you can then utilize the type checking features. Below is an example of how to create a JSDoc multi-line comment for type checking.

Custom JSDoc Multiline Comment with Custom Infer Expectations

/**
  * Test case scenario for JavaScript inferjs function.
  * @category tests
  * @function foo
  * @param {string} msg - The message to send through console.log().
  * @param {(number|string)} id - The id of the message.
  * @param {boolean} [send=true] - Whether to send your message.
  * @infer {string} msg {STRING-NOT-EMPTY} - Checks if string is not empty.
  * @inferid foo
  */
function foo(msg, id, send) {

  inferjs.check('foo', arguments);
}
   
// Example Normal Call
foo('test', 1234, true);

InferJS-Library: Type Checking with JSDoc @param

The JSDoc tag @param below, specifies a method's parameter type(s), name and description.

Fomart for @param:

  • @param {type} paramName - description
  • @param {(type|type)} paramName - description

Single type check example:

/**
  * @param {string} msg - The message to send through console.log().
  */

Multi type check example:

/**
  * @param {(null|string)} msg - The message to send through console.log().
  */

InferJS-Library reads the precompiled InferObject file and uses it to process all type checking and inferred expectations.

Below is a list of standard and extended types that can be checked:

Standard JS Types Description
undefined An undefined type: undefined
null A null type: null
boolean A boolean type: true or false
number A number type: 1000 or 10.25
bigint A big integer type: 1010101112233343545545545446n
string A string type: foo1 or foo2
symbol A symbol type: Symbol
function A function type: function
Extended JS Types Description
array An array type: []
infinity An infinity number type: Infinity
nan Not a number type: NaN
arguments The arguments object: arguments.
"className" A class name: fooClass
"functionName" A function name: fooFunction
"errorName" An error type: Error or TypeError or errorName

InferJS-Library: Expectation Checking with Tag @infer

InferJS-Library also allows for extended type checking with the custom @infer tag. Add one or multiple @infer tags to any parameter type. This will allow for narrowing your types down through expectations.

Below is an simple example of @infer:

Fomart for @infer

  • @infer {type} paramName {expectation} - description
  • @infer {(type|type)} paramName {(expectation|expectation)} - description
/**
  * @infer {string} msg {STRING-NOT-EMPTY} - Checks if string is not empty.
  */

The @infer tag is so versatile you can attach it to multiple types in a group and specify multiple narrowing and values to check against, like so:

/**
  * @infer {(number|string)} msg {INT32|STRING-NOT-EMPTY} - Checks if string is not empty and is an integer32.
  * @infer {array} arrname {IN-ARRAY=a,b,c,d,e} - Checks if a,b,c,d is in array.
  * @infer {object} objname {PROPS=id,name} - Checks if objname has properties id and name.
  */

InferJS-Library: Tag @infer Expectation Types

There are many extended expectation types for narrowing your types down with your @infer tags.

Below is a list of common rule expectation types:

Expectation Description
STRING-NOT-EMPTY Checks if a string is not empty.
STRING-EMPTY Checks if a string is empty.
IS-BOOL Checks if a string is a boolean, true, false, yes, no, on, off, 0, 1.
BETWEEN Checks if number is between two numbers.
BETWEEN-INCLUSIVE Checks if number is between two numbers and including equal to self.
BETWEEN-BIGINT Checks if string is between two big integers.
BETWEEN-BIGINT-INCLUSIVE Checks if a string is between two big integers including equal to self.
GREATER-THAN Checks if value is greater than.
GREATER-THAN-EQUAL Checks if value is greater than equal.
LESS-THAN Checks if value is less than.
LESS-THAN-EQUAL Checks if value is less than equal.
ALPHA Checks if alpha characters.
IS-NUMBER Checks if a string is a number.
IS-BIGINT Checks if a string is a bigint.
IS-NUMERIC Checks if a string is numeric.
ALPHA-NUMERIC Checks if a string is alpha numeric.
IN-ARRAY-CI Checks if in array list case insensitive.
IN-ARRAY Checks if in array list case sensitive.
NOT-IN-ARRAY-CI Checks if not in array list case insensitive.
NOT-IN-ARRAY Checks if not in array list case sensitive.
EXTENDS-ALL Checks if object extends all types.
EXTENDS Checks if object extends type.
PROPS Checks if object contains properties.
ARRAY-NOT-EMPTY Checks if array not empty.
ARRAY-EMPTY Checks if array is empty.
ARRAY-TYPES Checks if array items of are of expected types.
INT8 Checks for INT8: -128 to 127
CHAR ^
UINT8 Checks for UINT8: 0 to 255
UCHAR ^
UNSIGNED-CHAR ^
INT16 Checks for INT16: -32768 to 32767
SHORT ^
SHORT-INT ^
SIGNED-SHORT ^
UINT16 Check for UINT16: 0 to 65535
UNSIGNED-SHORT ^
UNSIGNED-SHORT-INT ^
USHORT ^
INT32 Check for INT32: -2147483648 to 2147483647
SIGNED-INT ^
INT ^
UINT32 Check for UINT32: 0 to 4294967295
UNSIGNED-INT ^
UINT ^
INT64 Check for INT64: -9223372036854775808 to 9223372036854775807
SIGNED-LONG ^
SIGNED-LONG-LONG ^
LONG ^
LONG-LONG ^
UINT64 Check for UINT64: 0 to 18446744073709551615
UNSIGNED-LONG ^
UNSIGNED-LONG-LONG ^
ULONG ^

InferJS-Library: Linking with Tag @inferid

The tag @inferid is a unique identifier for linking InferJS-Library behind the scenes. It is required for each method, property or field, you would like to check.

This special tag, allows code to still work, while JavaScript is compressed/minified or obfuscated. All Infers are stored in a precompiled InferObject file. This makes it easy to write in your static data types and not have to worry about type checking them during JavaScript Runtime execution.

@inferid can be anything you want as a name, but must be unique per item you want to check.

Below is an example of @inferid

Fomart for @inferid

  • @inferid uniqueId
/**
  * @inferid foo
  */

InferJS-Library: Running InferJS Checks with Method check()

To check all your types and expectations, you need to call the InferJS-Library method check(). It needs to be added at the beginning of each method(s) starting closure or below each variable you would like to check.

Below is the overload signature for the method check()

Method Signature for InferJS-Library: check()
check ( inferId: @inferid, args: arguments, returnException: boolean = false )
Description: Type checks all parameters in arguments list and either returns or throws exception.
check ( inferId: @inferid, arg: field, returnException: boolean = false )
Description: Type checks single declared variables or fields.

Example Check All Method Params:

function foo(){
  inferjs.check('Your - @inferid', arguments);
}

Example Check Field or Variable:

var a = 'foo';
inferjs.check('Your - @inferid', a);  

InferJS Library: Type Checking Errors

In InferJS-Library you have the option to throw or return exception from the check() method. Thrown errors come with tons of information for debugging your types and expectations.

Exception Types Description
InferUnhandledError For all errors unhandled by the InferJS-Library.
InferTypeError For all type errors created from the JSDoc tag @param {type}
InferExpectError For all errors related to the custom JSDoc tag @infer and custom expectation rules.

Below are examples of exception type responses from InferJS-Library.

> InferTypeError Example:

InferTypeError: Incorrect third parameter type in:
File: /path/to/test1.js
Line: 14
@inferid: foo
@function: ( msg: <string>, id: <number>, objectTester: <object< )
@param: objectTester
Expected Type: object
Actual Type: null

> InferExpectError Example:

InferExpectError: Incorrect first parameter, failed infer expectation type check in:
File: /path/to/test1.js
Line: 14
@inferid: foo
@function: foo( msg: <string|number|null>, id: <number|string>, send: <boolean> )
@param: msg
Expectation Type: STRING-NOT-EMPTY
Expectation Value: "1234"
Argument Value: ""

For more examples, please refer to the Documentation

PACK VERSION: LIC: MIT
COPYRIGHT © 2022-2024 INFERJS