Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

blork

Package Overview
Dependencies
Maintainers
1
Versions
56
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

blork

Blork! Mini runtime type checking in Javascript

  • 7.0.2
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
8.5K
decreased by-72.78%
Maintainers
1
Weekly downloads
 
Created
Source

Blork! Mini runtime type checking in Javascript

Build Status Prettier npm

A mini type checker for locking down the external edges of your code. Mainly for use in modules when you don"t know who'll be using the code. Minimal boilerplate code keeps your functions hyper readable and lets them be their beautiful minimal best selves (...or something?)

Blork is fully unit tested and 100% covered (if you're into that!).

Installation

npm install blork

Usage

args(): Check function arguments

The primary use case of Blork is validating function input arguments. The args() function is provided for this purpose, and should be passed two arguments:

  1. arguments | The arguments object provided automatically to functions in Javascript
  2. types | An array identifying the types for the arguments (list of types is available below)
import { args } from "blork";

// An exported function other (untrusted) developers may use.
export default function myFunc(definitelyString, optionalNumber)
{
	// Check the args.
	args(arguments, ["string", "number?"]);

	// Rest of the function.
	return "It passed!";
}

// Call with good args.
myFunc("abc", 123); // Returns "It passed!"
myFunc("abc"); // Returns "It passed!"

// Call with invalid args.
myFunc(123); // Throws ValueError "arguments[0]: Must be string (received 123)"
myFunc("abc", "abc"); // Throws ValueError "arguments[1]: Must be number (received "abc")"
myFunc(); // Throws ValueError "arguments[0]: Must be string (received undefined)"
myFunc("abc", 123, true); // Throws ValueError "arguments: Too many arguments (expected 2) (received 3)"

check(): Check individual values

The check() function allows you to test individual values with more granularity. The check() function is more versatile and allows more use cases than validating function input arguments.

check() accepts three arguments:

  1. value The value to check
  2. type The type to check the value against (list of types is available below)
  3. prefix An optional string name/prefix for the value, which is prepended to any error message thrown to help debugging
import { check } from "blork";

// Checks that pass.
check("Sally", "string"); // No error.
check("Sally", String); // No error.

// Checks that fail.
check("Sally", "number"); // Throws ValueError "Must be number (received "Sally")"
check("Sally", Boolean); // Throws ValueError "Must be true or false (received "Sally")"

// Checks that fail (with a prefix/name set).
check("Sally", "num", "name"); // Throws ValueError "name: Must be number (received "Sally")"
check(true, "str", "status"); // Throws ValueError "status: Must be string (received true)"

Another common use for check() is to validate an options object:

import { check } from "blork";

// Make a custom function.
function myFunc(options)
{
	// Check all the options with a literal type (note that keepAlive is optional).
	check(options, { name: "string", required: "boolean", keepAlive: "number?" });
}

There are more complex types available: Appending ? question mark to any type string makes it optional (which means it also allows undefined). Prepending a ! exclaimation mark to any type string makes it inverted. Multiple types can be combined with | and & for OR and AND conditions.

// Optional types.
check(undefined, "number"); // Throws ValueError "Must be number (received undefined)"
check(undefined, "number?"); // No error.

// Note that null does not count as optional.
check(null, "number?"); // Throws ValueError "Must be number (received null)"

// Inverted types.
check(123, "!str"); // No error.
check(123, "!int"); // Throws ValueError "Must be not integer (received 123)"

// Combined OR types.
check(1234, "num | str"); // No error.
check(null, "num | str"); // Throws ValueError "Must be number or string (received null)"

// Combined AND types.
check("abc", "string & !falsy"); // No error.
check("", "string & !falsy"); // Throws ValueError "Must be string and not falsy (received "")"

Checking objects and arrays

Blork can perform deep checks on objects and arrays to ensure the schema is correct. To do object or array checks pass literal arrays or literal objects to check() or args():

// Check object properties.
check({ name: "Sally" }, { name: "string" }); // No error.

// Check all array items.
check(["Sally", "John", "Sonia"], ["str"]); // No error.

// Check tuple-style array.
check([1029, "Sonia"], ["number", "string"]); // No error.

// Failing checks.
check({ name: "Sally" }, { name: "string" }); // No error.
check(["Sally", "John", "Sonia"], ["str"]); // No error.
check([1029, "Sonia"], ["number", "string"]); // No error.
check([1029, "Sonia", true], ["number", "string"]); // Throws ValueError: "Array: Too many array items (expected 2) (received 3)"

Arrays and objects can be deeply nested within each other and Blork will recursively check the schema all the way down:

// Deeply nested check (passes).
// Will return 1
check(
	[
		{ id: 1028, name: "Sally", status: [1, 2, 3] },
		{ id: 1062, name: "Bobby", status: [1, 2, 3] }
	],
	[
		{ id: Number, name: String, status: [Number] }
	]
);

// Deeply nested check (fails).
// Will throw ValueError "Array[1][status][2]: Must be number (received "not_a_number")"
check(
	[
		{ id: 1028, name: "Sally", status: [1, 2, 3] },
		{ id: 1062, name: "Bobby", status: [1, 2, "not_a_number"] }
	],
	[
		{ id: Number, name: String, status: [Number] }
	]
);

add(): Add a custom checker type

Register your own checker using the add() function. This is great if 1) you're going to be applying the same check over and over, or 2) want to integrate your own checks with Blork's built-in types so your code looks clean.

add() accepts four arguments:

  1. name The name of the custom checker (only kebab-case strings allowed).
  2. checker A function that accepts a single argument, value, and returns true or false.
  3. description="" An description for the value the checker will accept, e.g. "lowercase string" or "unique username", that is shown in the error message. Defaults to the value of name.
  4. error=undefined A custom class that is thrown when this checker fails (can be [VALUES]_ class, not just classes extending Error). An error set with add() takes precedence for this checker over the error set through throws()`.
import { add, check } from "blork";

// Register your new checker.
add(
	// Name of checker.
	"catty",
	// Checker to validate a string containing "cat".
	(v) => typeof v === "string" && v.strToLower().indexOf("cat") >= 0,
	// Description of what the variable _should_ contain.
	// Gets shown in the error message.
	"string containing 'cat'"
);

// Passes.
check("That cat is having fun", "catty"); // No error.
check("That CAT is having fun", "catty"); // No error.

// Fails.
check("A dog sits on the chair", "catty"); // Throws ValueError "Must be string containing "cat" (received "A dog sits on the chair")"

// Combine a custom checkers with a built-in checker using `&` syntax.
// The value must pass both checks or an error will be thrown.
// This saves you replicating existing logic in your checker.
check("A CAT SAT ON THE MAT", "upper+ & catty"); // No error.
check("A DOG SAT ON THE MAT", "upper+ & catty"); // Throws ValueError "Must be non-empty uppercase string and string containing 'cat'"
import { add, args } from "blork";

// Use your checker to check function args.
function myFunc(str)
{
	// Validate the function's args!
	args(arguments, ["catty"]);

	// Big success.
	return "It passed!";
}

// Passes.
myFunc("That cat is chasing string"); // Returns "It passed!"

// Fails.
myFunc("A dog sits over there"); // Throws ValueError "arguments[1]: Must be string containing "cat" (received "A dog sits over there")"

throws(): Set a custom error constructor

To change the error object Blork throws when a type doesn't match, use the throws() function. It accepts a single argument a custom class (can be [VALUES]_ class, not just classes extending Error).

import { throws, check } from "blork";

// Make a custom error type for yourself.
class MyError extends Error {};

// Register your custom error type.
throws(MyError);

// Test a value.
check(true, "false"); // Throws MyError "Must be false (received true)"

blork(): Create an independent instance of Blork

To create an instance of Blork with an independent set of checkers (added with add()) and an independently set throws() error object, use the blork() function.

This functionality is provided so you can ensure multiple versions of Blork in submodules of the same project don't interfere with each other, even if they have been (possibly purposefully) deduped in npm. This is how you can ensure if you've set a custom error for a set of checks, that custom error type is always thrown.

import { blork } from "blork";

// Create a new set of functions from Blork.
const { check, args, add, throws } = blork();

// Set a new custom error on the new instance.
throws(class CustomError extends ValueError);

// Add a custom checker on the new instance.
add("mychecker", v => v === "abc", "'abc'");

// Try to use the custom checker.
check("123", "mychecker"); // Throws CustomChecker("Must be 'abc' (received '123')")

props(): Define Blork-checked object properties

The props() function can define an object properties (like Object.defineProperties()) that are readable and writable, BUT the value must always match the type it was initially defined with.

This allows you to create objects with properties that have a guaranteed type. This makes your object more robust and removes the need to check the type of the property before using it.

props() accepts two arguments:

  1. object The object to define the property on
  2. props A set of properties to define on the object and lock down
import { prop } from "blork";

// Make an object.
const obj = {};

// Define typed properties on the object.
props(obj, {
	"name": "Mel",
	"coords": { lat: 0, lng: 0 },
	"map": new Map()
});

// Setting the value to an allowed type is fine.
obj.name = "John";
obj.coords = { lat: 28.20, lng: 12.00 };
obj.map = new Map();

// Setting the value to a disallowed type is not fine.
obj.name = 123; // Throws TypeError "name: Must be string (received 123)"
obj.coords = 123; // Throws TypeError "coords: Must be plain object (received 123)"
obj.coords = { lat: "abc", lng: 0 }; // Throws TypeError "coords.lat: Must be number (received "abc")"
obj.map = new Set(); // Throws TypeError "map: must be instance of Map (received Set)
import { prop } from "blork";

// Make an object.
const obj = {};

debug(): Debug any value as a string.

Blork exposes its debugger helper function debug(), which it uses to format error messages correctly. debug() accepts any argument and will return a clear string interpretation of the value.

debug() deals well with large and nested objects/arrays by inserting linebreaks and tabs if line length would be unreasonable. Output is also kept cleanish by only debugging 3 levels deep, truncating long strings, and not recursing into circular references.

import debug from "blork";

// Debug primitives.
debug(undefined); // Returns `undefined`
debug(null); // Returns `null`
debug(true); // Returns `true`
debug(false); // Returns `false`
debug(123); // Returns `123`
debug("abc"); // Returns `"abc"`
debug(Symbol("abc")); // Returns `Symbol("abc")`

// Debug functions.
debug(function dog() {}); // Returns `dog()`
debug(function() {}); // Returns `anonymous function()`

// Debug objects.
debug({}); // Returns `{}`
debug({ a: 123 }); // Returns `{ "a": 123 }`
debug(new Promise()); // Returns `Promise {}`
debug(new MyClass()); // Returns `MyClass {}`
debug(new class {}()); // Returns `anonymous class {}`

ValueError: Great debuggable error class

Internally, when there's a problem with a value, Blork will throw a ValueError. This value extends TypeError and standardises error message formats, so errors are consistent and provide the detail a developer should need to debug the issue error quickly and easily.

It accepts three values:

  1. message The error message describing the issue with the value, e.g. "Must be string"
  2. value The actual value that was incorrect so a debugged version of this value can appear in the error message, e.g. (received 123)
  3. prefix A string prefix for the error that should identify the location the error occurred and the name of the value, e.g. "myFunction(): name"
import { ValueError } from "blork";

// Function that checks its argument.
function myFunc(name) {
	// If name isn't a string, throw a ValueError.
	// (This is essentially what check() does behind the scenes.)
	if (typeof name !== "string") throw new ValueError("Must be string", name, "myFunc(): name");
}

// Call with incorrect name.
myFunc(123); // Throws ValueError "myFunc(): name: Must be a string (received 123)"

Type reference

This section lists all types that are available in Blork. A number of different formats can be used for types:

  • String types (e.g. "promise" and "integer")
  • String modifiers that modify those string types (e.g. "?" and "!")
  • Constant and constructor shorthand types (e.g. null and String)
  • Object and Array literal types (e.g. {} and [])

String types: primitives

Type stringDescription
primitiveAny primitive value (undefined, null, booleans, strings, finite numbers)
nullValue is null
undefined, undef, voidValue is undefined
defined, defValue is not undefined

String types: booleans

Type stringDescription
boolean, boolValue is true or false
trueValue is true
falseValue is false
truthyAny truthy values (i.e. == true)
falsyAny falsy values (i.e. == false)

String types: numbers

Type stringDescription
zeroValue is 0
oneValue is 1
nanValue is NaN
number, numAny numbers except NaN/Infinity (using Number.isFinite())
+number, +num,Numbers more than or equal to zero
-number, -numNumbers less than or equal to zero
integer, intIntegers (using Number.isInteger())
+integer, +intPositive integers including zero
-integer, -intNegative integers including zero

String types: strings

Type stringDescription
string, strAny strings (using typeof)
lowerlowercase string (non-empty and alphanumeric only)
upperUPPERCASE strings (non-empty and alphanumeric only)
camelcamelCase strings e.g. variable/function names (non-empty alphanumeric with lowercase first letter)
pascalPascalCase strings e.g. class names (non-empty alphanumeric with uppercase first letter)
snakesnake_case strings (non-empty alphanumeric lowercase)
screamingSCREAMING_SNAKE_CASE strings e.g. environment vars (non-empty uppercase alphanumeric)
kebab, slugkebab-case strings e.g. URL slugs (non-empty alphanumeric lowercase)
trainTrain-Case strings e.g. HTTP-Headers (non-empty with uppercase first letters)

String types: objects

Type stringDescription
function, funcFunctions (using instanceof Function)
object, objPlain objects (using typeof && !null and constructor check)
objectlikeAny object-like object (using typeof && !null)
iterableObjects with a Symbol.iterator method (that can be used with for..of loops)
circularObjects with one or more circular references (use !circular to disallow circular references)
array, arrPlain arrays (using instanceof Array and constructor check)
arraylike, arguments, argsArray-like objects, e.g. arguments (any object with numeric .length property, not just arrays)
mapInstances of Map
weakmapInstances of WeakMap
setInstances of Set
weaksetInstances of WeakSet
promiseInstances of Promise
dateInstances of Date
futureInstances of Date with a value in the future
pastInstances of Date with a value in the past
regex, regexpInstances of RegExp (regular expressions)
symbolValue is Symbol (using typeof)

String types: other

Type stringDescription
any, mixedAllow any value (transparently passes through with no error)
json, jsonableJSON-friendly values (null, true, false, finite numbers, strings, plain objects, plain arrays)
// Pass.
check("abc", "str"); // No error.
check("abc", "lower"); // No error.
check(100, "integer"); // No error.
check([1, 2, 3], "array+"); // No error.
check(new Date(2180, 1, 1), "future"); // No error.
check(new Map([[1, 1], [2, 2]]), "map+"); // No error.

// Fail.
check(123, "str"); // Throws ValueError "Must be string (received 123)"
check({}, "object+"); // Throws ValueError "Must be object with one or more properties (received Object(0))"
check([], "array+"); // Throws ValueError "Must be array with one or more items (received Array(0))"

String modifiers: Optional types

Any string type can be made optional by appending a ? question mark to the type reference. This means the check will also accept undefined in addition to the specified type.

// Pass.
check(undefined, "str?"); // No error.
check(undefined, "lower?"); // No error.
check(undefined, "int?"); // No error.
check([undefined, undefined, 123], ["number?"]); // No error.

// Fail.
check(123, "str?"); // Throws ValueError "Must be string (received 123)"
check(null, "str?"); // Throws ValueError "Must be string (received null)"

String modifiers: Non-empty types

Any type can be made non-empty by appending a + plus sign to the type reference. This means the check will only pass if the value is non-empty and has length.

// Pass.
check("abc", "str+"); // No error.
check([1], "arr+"); // No error.
check({ a: 1 }, "obj+"); // No error.

// Fail.
check(123, "str+"); // Throws ValueError "Must be non-empty string (received "")"
check([], "arr+"); // Throws ValueError "Must be non-empty plain array (received [])"
check({}, "obj+"); // Throws ValueError "Must be non-empty plain object (received {})"

String modifiers: Inverted types

Any string type can be made optional by prepending a ! question mark to the type reference. This means the check will only pass if the inverse of its type is true.

// Pass.
check(undefined, "!str"); // No error.
check("Abc", "!lower"); // No error.
check(123.456, "!integer"); // No error.
check([undefined, "abc", true, false], ["!number"]); // No error.

// Fail.
check(123, "!str"); // Throws ValueError "Must be not string (received "abc")"
check(true, "!bool"); // Throws ValueError "Must be not true or false (received true)"
check([undefined, "abc", true, 123], ["!number"]); // Throws ValueError "array[3]: Must be not number (received 123)"

String modifiers: Combined types

You can use & and | to join string types together, to form AND and OR chains of allowed types. This allows you to compose together more complex types like number | string or date | number | null or string && custom-checker

| is used to create an OR type, meaning any of the values is valid, e.g. number|string or string | null

// Pass.
check(123, "str|num"); // No error.
check("a", "str|num"); // No error.

// Fail.
check(null, "str|num"); // Throws ValueError "Must be string or number (received null)"
check(null, "str|num|bool|func|obj"); // Throws ValueError "Must be string or number or boolean or function or object (received null)"

& is used to create an AND type, meaning the value must pass all of the checks to be valid. This is primarily useful for custom checkers e.g. lower & username-unique.

// Add a checker that confirms a string contains the word "cat"
add("catty", v => v.toLowerCase().indexOf("cat") >= 0);

// Pass.
check("this cat is crazy!", "lower & catty"); // No error.
check("THIS CAT IS CRAZY", "upper & catty"); // No error.

// Fail.
check("THIS CAT IS CRAZY", "lower & catty"); // Throws ValueError "Must be lowercase string and catty"
check("THIS DOG IS CRAZY", "string & catty"); // Throws ValueError "Must be string and catty"

Note: & has a higher precedence than |, meaning a type like string & lower | upper compiles to (lower | upper) & string.

Note: All built in checkers like lower or int+ already check the basic type of a value, so there's no need to use string & lower or number & int+. These will work but you'll be double checking.

Note: Spaces around the & or | are not required (but can be more readable).

Constructor and constant types

For convenience some constructors (e.g. String) and constants (e.g. null) can be used as types in args() and check(). The following built-in objects and constants are supported:

TypeDescription
BooleanSame as 'boolean' type
StringSame as 'string' type
NumberSame as 'number' type
trueSame as 'true' type
falseSame as 'false' type
nullSame as 'null' type
undefinedSame as 'undefined' type

You can pass in any class name, and Blork will check the value using instanceof and generate a corresponding error message if the type doesn't match.

Using Object and Array constructors will work also and will allow any object that is instanceof Object or instanceof Array. Note: this is not the same as e.g. the 'object' and 'array' string types, which only allow plain objects and arrays.

// Pass.
check(true, Boolean); // No error.
check("abc", String); // No error.
check(123, Number); // No error.
check(new Date, Date); // No error.
check(new MyClass, MyClass); // No error.
check(Promise.resolved(true), Promise); // No error.
check([true, true, false], [Boolean]); // No error.
check({ name: 123 }, { name: Number }); // No error.

// Fail.
check("abc", Boolean); // Throws ValueError "Must be true or false (received "abc")"
check("abc", String); // Throws ValueError "Must be string (received "abc")"
check("abc", String, "myVar"); // Throws ValueError "myVar: Must be string (received "abc")"
check(new MyClass, OtherClass); // Throws ValueError "Must ben instance of OtherClass (received MyClass)"
check({ name: 123 }, { name: String }); // Throws ValueError "name: Must be string (received 123)"
check({ name: 123 }, { name: String }, "myObj"); // Throws ValueError "myObj[name]: Must be string (received 123)"

Object literal type

To check the types of object properties, use a literal object as a type. You can also deeply nest these properties and the types will be checked recursively and will generate useful debuggable error messages.

Note: it is fine for objects to contain additional properties that don't have a type specified.

// Pass.
check({ name: "abc" }, { name: "str" }); // No error.
check({ name: "abc" }, { name: "str?", age: "num?" }); // No error.
check({ name: "abc", additional: true }, { name: "str" }); // Throws nothing (additional properties are fine).

// Fail.
check({ age: "apple" }, { age: "num" }); // Throws ValueError "age: Must be number (received "apple")"
check({ size: { height: 10, width: "abc" } }, { size: { height: "num", width: "num" } }); // Throws ValueError "size[width]: Must be number (received "abc")"

Object literal type: additional values

To check that the type of any properties conform to a single type, use the VALUES symbol and create a [VALUES] key. This allows you to check objects that don't have known keys (e.g. from user generated data). This is similar to how indexer keys work in Flow or Typescript.

import { check, VALUES } from "blork";

// Pass.
check(
	{ a: 1, b: 2, c: 3 },
	{ [VALUES]: "num" }
); // No error.
check(
	{ name: "Dan", a: 1, b: 2, c: 3 },
	{ name: "str", [VALUES]: "num" }
); // No error.

// Fail.
check(
	{ a: 1, b: 2, c: "abc" },
	{ [VALUES]: "num" }
); // Throws ValueError "c: Must be number..."
check(
	{ name: "Dan", a: 1, b: 2, c: 3 },
	{ name: "str", [VALUES]: "bool" }
); // Throws ValueError "a: Must be boolean..."

You can use this functionality with the undefined type to ensure objects do not contain additional properties (object literal types by default are allowed to contain additional properties).

// Pass.
check(
	{ name: "Carl" },
	{ name: "str", [VALUES]: "undefined" }
); // No error.

// Fail.
check(
	{ name: "Jess", another: 28 },
	{ name: "str", [VALUES]: "undefined" }
); // Throws ValueError "another: Must be undefined..."

Object literal type: additional keys

To check that the keys of any additional properties conform to a single type, use the KEYS symbol and create a [KEYS] key. This allows you to ensure that keys conform to a specific string type, e.g. camelCase, kebab-case or UPPERCASE (see string types above).

import { check, VALUES } from "blork";

// Pass.
check({ MYVAL: 1 }, { [KEYS]: "upper" }); // UPPERCASE keys — no error.
check({ myVal: 1 }, { [KEYS]: "camel" }); // camelCase keys — no error.
check({ MyVal: 1 }, { [KEYS]: "pascal" }); // PascalCase keys — no error.
check({ my-val: 1 }, { [KEYS]: "kebab" }); // kebab-case keys — no error.

// Fail.
check({ MYVAL: 1 }, { [KEYS]: "upper" }); // UPPERCASE keys — no error.
check({ myVal: 1 }, { [KEYS]: "camel" }); // camelCase keys — no error.
check({ MyVal: 1 }, { [KEYS]: "pascal" }); // PascalCase keys — no error.
check({ my-val: 1 }, { [KEYS]: "kebab" }); // kebab-case keys — no error.

Object literal type: custom constructor

Normally object literal types check that the object is a plain object. If you wish to allow the object to be a different object, use the CLASS symbol and create a [CLASS] key.

import { check, CLASS } from "blork";

// Make a fancy new class.
class MyClass {
	constructor () {
		this.num = 123;
	}
}

// Pass.
check(
	new MyClass,
	{ num: 123, [CLASS]: MyClass }
); // No error.

// Fail.
check(
	{ num: 123, },
	{ num: 123, [CLASS]: MyClass }
); // Throws ValueError "Must be instance of MyClass..."

Array literal type

To check an array where all items conform to a specific type, pass an array as the type. Arrays and objects can be deeply nested to check types recursively.

// Pass.
check(["abc", "abc"], ["str"]); // No error.
check([123, 123], ["num"]); // No error.
check([{ names: ["Alice", "John"] }], [{ names: ["str"] }]); // No error.

// Fail.
check(["abc", "abc", 123], ["str"]); // Throws ValueError "Array[2]: Must be number (received 123)"
check(["abc", "abc", 123], ["number"]); // Throws ValueError "Array[0]: Must be string (received "abc")"

Array tuple type

Similarly, to check the format of tuples, pass an array with two or more items as the type. If two or more types are in an type array, it is considered a tuple type and will be rejected if it does not conform exactly to the tuple.

// Pass.
check([123, "abc"], ["num", "str"]); // No error.
check([123, "abc"], ["num", "str", "str?"]); // No error.

// Fail.
check([123], ["num", "str"]); // Throws ValueError "Array[1]: Must be string (received undefined)"
check([123, 123], ["num", "str"]); // Throws ValueError "Array[1]: Must be string (received 123)"
check([123, "abc", true], ["num", "str"]); // Throws ValueError "Array: Too many items (expected 2 but received 3)"

Contributing

Please see (CONTRIBUTING.md)

Roadmap

  • Support @decorator syntax for class methods (PRs welcome)

Changelog

  • 7.0.0
    • Add VALUES, KEYS, and CLASS symbol constants
    • Remove _any key and use VALUES to provide the same functionality
    • Add KEYS functionality to check type or case of object keys, e.g. camelCase or kebab-case
    • Add CLASS functionality to check the class of an object
    • Add string case checkers for e.g. variable names (kebab-case, camelCase, snake_case etc)
    • upper and lower checkers work differently (all characters must be UPPERCASE/lowercase)
    • Rename int+, int- checkers to +int and -int
    • Add '+' modifier to check for non-empty values with any checker
    • Remove hardcoded '+' checkers like lower+, object+
    • Remove uppercase and lowercase checkers for consistency
  • 6.0.0
    • Remove prop() function and add props() function instead (prop() was impossible to type with Flow)
  • 5.1.0
    • Add prop() function that defines a locked object property that must match a Blork type
  • 5.0.0
    • Change from symbol [ANY] key to [VALUES] key for indexer property (for convenience and better Flow compatibility)
  • 4.5.0
    • Add checker() function to return the boolean checker function itself.
  • 4.4.0
    • Add json checker to check for JSON-friendly values (null, true, false, finite numbers, strings, plain objects, plain arrays)
  • 4.3.0
    • Add circular checker to check for objects with circular references
    • Add ! modifier to enable invert checking, e.g. !num (don't allow numbers) or !circular (don't allow circular references)
  • 4.2.2
    • Use . dot notation in error message prefix when recursing into objects
  • 4.2.1
    • Fix bug where optional types were throwing an incorrect error message
  • 4.2.0
    • Rename FormattedError to ValueError (more descriptive and reusable name)
    • Make ValueError the default error thrown by Blork (not ValueError)
  • 4.1.0
    • Allow custom error to be set for custom checkers via add()
    • Export debug() which allows any value to be converted to a string in a clean and clear format
    • Export format() which takes three arguments (message, value, prefix) and returns a consistently and beautifully formatted error message.
    • Export FormattedError which takes the same three arguments and applies format() so it always has beautiful errors
    • Export BlorkError (which is thrown when you're using Blork wrong) for the purposes of checking thrown errors against it
  • 4.0.0
    • Major internal rewrite with API kept almost the same
    • Add support for combining checkers with | and & syntax
    • check() and args() no longer return anything (previously returned the number of passing values)
    • Custom checkers should now return boolean (message/description for the checker can be passed in as third field to add())

FAQs

Package last updated on 15 May 2018

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc