New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.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 - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

lib/internal.d.ts

6

lib/blork.d.ts

@@ -1,5 +0,5 @@

import { CheckerFunction, ArgumentsObject, TypesArray, ErrorConstructor } from './types';
export declare function check(value: any, type: any, prefix?: string): number;
export declare function args(args: ArgumentsObject, types: TypesArray): number;
import { CheckerFunction, ArgumentsObject, Types, TypesArray, ErrorConstructor } from './types';
export declare function check(value: any, type: Types, prefix?: string): number;
export declare function args(argsObj: ArgumentsObject, types: TypesArray): number;
export declare function add(name: string, checker: CheckerFunction): void;
export declare function throws(err: ErrorConstructor): void;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const internal_1 = require("./internal");
const checkers_1 = require("./checkers");

@@ -8,16 +9,17 @@ const helpers_1 = require("./helpers");

function check(value, type, prefix = '') {
safe(prefix, 'string', 'arguments[2]', errors_1.BlorkError);
return safe(value, type, prefix, errorConstructor);
internal_1.internalCheck(prefix, 'string', 'arguments[2]', errors_1.BlorkError);
return internal_1.internalCheck(value, type, prefix, errorConstructor);
}
exports.check = check;
function args(args, types) {
safe(args, 'args', 'arguments[0]', errors_1.BlorkError);
safe(types, 'array', 'arguments[1]', errors_1.BlorkError);
function args(argsObj, types) {
internal_1.internalCheckString(argsObj, 'args', 'arguments[0]', errors_1.BlorkError);
internal_1.internalCheckString(types, 'array', 'arguments[1]', errors_1.BlorkError);
const l = types.length;
let pass = 0;
const l = types.length;
for (let i = 0; i < l; i++)
if (safe(args[i], types[i], 'arguments[' + i + ']', errorConstructor))
if (internal_1.internalCheck(argsObj[i], types[i], `arguments[${i}]`, errorConstructor))
pass++;
if (args.length > l)
throw new errorConstructor(helpers_1.format('Must not have more than ' + l + ' arguments', args.length, 'arguments'));
if (argsObj.length > l) {
throw new errorConstructor(helpers_1.format(`Must not have more than ${l} arguments`, argsObj.length, 'arguments'));
}
return pass;

@@ -27,6 +29,7 @@ }

function add(name, checker) {
safe(name, 'lower+', 'arguments[0]', errors_1.BlorkError);
safe(checker, 'function', 'arguments[1]', errors_1.BlorkError);
if (checkers_1.checkers[name])
throw new errors_1.BlorkError("Checker '" + name + " already exists");
internal_1.internalCheckString(name, 'lower+', 'arguments[0]', errors_1.BlorkError);
internal_1.internalCheckString(checker, 'function', 'arguments[1]', errors_1.BlorkError);
if (checkers_1.checkers[name]) {
throw new errors_1.BlorkError(`Blork type '${name}' already exists`);
}
checkers_1.checkers[name] = checker;

@@ -36,81 +39,6 @@ }

function throws(err) {
safe(err, 'function', 'arguments[0]', errors_1.BlorkError);
internal_1.internalCheckString(err, 'function', 'arguments[0]', errors_1.BlorkError);
errorConstructor = err;
}
exports.throws = throws;
function safe(value, type, name, errorConstructor) {
if (typeof type === 'string') {
let checker = checkers_1.checkers[type];
if (!checker) {
if (type.length && type[type.length - 1] === '?') {
checker = checkers_1.checkers[type.slice(0, -1)];
if (checker && value === undefined)
return 0;
}
if (!checker)
throw new errors_1.BlorkError("Checker '" + type + "' does not exist");
}
const result = checker(value);
if (result === true)
return 1;
else if (typeof result === 'string')
throw new errorConstructor(helpers_1.format(result, value, name));
else
throw new errors_1.BlorkError(helpers_1.format("Checker '" + type + "' did not return true or string", result));
}
else if (type instanceof Function) {
let result = true;
switch (type) {
case Boolean:
result = checkers_1.checkers.bool(value);
break;
case Number:
result = checkers_1.checkers.num(value);
break;
case String:
result = checkers_1.checkers.str(value);
break;
case Object:
result = checkers_1.checkers.obj(value);
break;
default: if (!(value instanceof type))
result = 'Must be instance of ' + (type.name || 'specified object');
}
if (typeof result === 'string')
throw new errorConstructor(helpers_1.format(result, value, name));
else
return 1;
}
else if (type instanceof Array) {
safe(value, 'array', name, errorConstructor);
if (!name.length)
name = 'Array';
let pass = 0;
if (type.length === 1) {
const l = value.length;
for (let i = 0; i < l; i++)
if (safe(value[i], type[0], name + '[' + i + ']', errorConstructor))
pass++;
}
else {
const l = type.length;
for (let i = 0; i < l; i++)
if (safe(value[i], type[i], name + '[' + i + ']', errorConstructor))
pass++;
if (value.length > l)
throw new errorConstructor(helpers_1.format('Must not have more than ' + l + ' array items', value.length, name));
}
return pass;
}
else if (type instanceof Object) {
safe(value, 'object', name, errorConstructor);
let pass = 0;
for (const key in type)
if (safe(value[key], type[key], (name ? name + '[' + key + ']' : key), errorConstructor))
pass++;
return pass;
}
else
throw new errors_1.BlorkError(helpers_1.format('Checker type must be a string, function, array, or object', type));
}
//# sourceMappingURL=blork.js.map

@@ -7,3 +7,3 @@ "use strict";

'defined': (v) => v !== undefined || 'Must be defined',
'boolean': (v) => (v === true || v === false) || 'Must be true or false',
'boolean': (v) => v === true || v === false || 'Must be true or false',
'true': (v) => v === true || 'Must be true',

@@ -14,48 +14,48 @@ 'false': (v) => v === false || 'Must be false',

'number': (v) => typeof v === 'number' || 'Must be number',
'integer': (v) => Number.isInteger(v) && v >= Number.MIN_SAFE_INTEGER && v <= Number.MAX_SAFE_INTEGER || 'Must be an integer',
'natural': (v) => Number.isInteger(v) && v > 0 && v <= Number.MAX_SAFE_INTEGER || 'Must be a natural number, e.g. 1, 2, 3',
'whole': (v) => Number.isInteger(v) && v >= 0 && v <= Number.MAX_SAFE_INTEGER || 'Must be a whole number, e.g. 0, 1, 2, 3',
'finite': (v) => Number.isFinite(v) || 'Must be a finite number',
'integer': (v) => (typeof v === 'number' && Number.isInteger(v) && v >= Number.MIN_SAFE_INTEGER && v <= Number.MAX_SAFE_INTEGER) || 'Must be an integer',
'natural': (v) => (typeof v === 'number' && Number.isInteger(v) && v > 0 && v <= Number.MAX_SAFE_INTEGER) || 'Must be a natural number, e.g. 1, 2, 3',
'whole': (v) => (typeof v === 'number' && Number.isInteger(v) && v >= 0 && v <= Number.MAX_SAFE_INTEGER) || 'Must be a whole number, e.g. 0, 1, 2, 3',
'finite': (v) => (typeof v === 'number' && Number.isFinite(v)) || 'Must be a finite number',
'string': (v) => typeof v === 'string' || 'Must be a string',
'string+': (v) => typeof v === 'string' && v.length > 0 || 'Must be a non-empty string',
'lowercase': (v) => typeof v === 'string' && v === v.toLowerCase() || 'Must be a lowercase string',
'lowercase+': (v) => typeof v === 'string' && v.length > 0 && v === v.toLowerCase() || 'Must be a non-empty lowercase string',
'uppercase': (v) => typeof v === 'string' && v === v.toUpperCase() || 'Must be an uppercase string',
'uppercase+': (v) => typeof v === 'string' && v.length > 0 && v === v.toUpperCase() || 'Must be a non-empty uppercase string',
'string+': (v) => (typeof v === 'string' && v.length > 0) || 'Must be a non-empty string',
'lowercase': (v) => (typeof v === 'string' && v === v.toLowerCase()) || 'Must be a lowercase string',
'lowercase+': (v) => (typeof v === 'string' && v.length > 0 && v === v.toLowerCase()) || 'Must be a non-empty lowercase string',
'uppercase': (v) => (typeof v === 'string' && v === v.toUpperCase()) || 'Must be an uppercase string',
'uppercase+': (v) => (typeof v === 'string' && v.length > 0 && v === v.toUpperCase()) || 'Must be a non-empty uppercase string',
'function': (v) => v instanceof Function || 'Must be an function',
'object': (v) => v instanceof Object || 'Must be an object',
'object+': (v) => v instanceof Object && Object.keys(v).length > 0 || 'Must be an object with one or more enumerable properties',
'iterable': (v) => v instanceof Object && typeof v[Symbol.iterator] === 'function' || 'Must be an iterable object',
'object': (v) => (typeof v === 'object' && v !== null) || 'Must be an object',
'object+': (v) => (typeof v === 'object' && v !== null && Object.keys(v).length > 0) || 'Must be an object with one or more enumerable properties',
'iterable': (v) => (typeof v === 'object' && v !== null && typeof v[Symbol.iterator] === 'function') || 'Must be an iterable object',
'array': (v) => v instanceof Array || 'Must be an array',
'array+': (v) => v instanceof Array && v.length > 0 || 'Must be a non-empty array',
'array+': (v) => (v instanceof Array && v.length > 0) || 'Must be a non-empty array',
'map': (v) => v instanceof Map || 'Must be a map',
'map+': (v) => v instanceof Map && v.size > 0 || 'Must be a non-empty map',
'map+': (v) => (v instanceof Map && v.size > 0) || 'Must be a non-empty map',
'weakmap': (v) => v instanceof WeakMap || 'Must be a weak map',
'set': (v) => v instanceof Set || 'Must be a set',
'set+': (v) => v instanceof Set && v.size > 0 || 'Must be a non-empty set',
'set+': (v) => (v instanceof Set && v.size > 0) || 'Must be a non-empty set',
'weakset': (v) => v instanceof WeakSet || 'Must be a weak set',
'arguments': (v) => v instanceof Object && typeof v.length === 'number' || 'Must be an arguments object',
'arguments': (v) => (typeof v === 'object' && v !== null && v.hasOwnProperty('length') && typeof v.length === 'number') || 'Must be an arguments object',
'promise': (v) => v instanceof Promise || 'Must be a promise',
'date': (v) => v instanceof Date || 'Must be a date',
'future': (v) => v instanceof Date && v.getTime() > Date.now() || 'Must be a date in the future',
'past': (v) => v instanceof Date && v.getTime() < Date.now() || 'Must be a date in the past',
'future': (v) => (v instanceof Date && v.getTime() > Date.now()) || 'Must be a date in the future',
'past': (v) => (v instanceof Date && v.getTime() < Date.now()) || 'Must be a date in the past',
};
exports.checkers['void'] = exports.checkers['undefined'];
exports.checkers['undef'] = exports.checkers['undefined'];
exports.checkers['def'] = exports.checkers['defined'];
exports.checkers['bool'] = exports.checkers['boolean'];
exports.checkers['num'] = exports.checkers['number'];
exports.checkers['int'] = exports.checkers['integer'];
exports.checkers['str'] = exports.checkers['string'];
exports.checkers.void = exports.checkers.undefined;
exports.checkers.undef = exports.checkers.undefined;
exports.checkers.def = exports.checkers.defined;
exports.checkers.bool = exports.checkers.boolean;
exports.checkers.num = exports.checkers.number;
exports.checkers.int = exports.checkers.integer;
exports.checkers.str = exports.checkers.string;
exports.checkers['str+'] = exports.checkers['string+'];
exports.checkers['lower'] = exports.checkers['lowercase'];
exports.checkers.lower = exports.checkers.lowercase;
exports.checkers['lower+'] = exports.checkers['lowercase+'];
exports.checkers['upper'] = exports.checkers['uppercase'];
exports.checkers.upper = exports.checkers.uppercase;
exports.checkers['upper+'] = exports.checkers['uppercase+'];
exports.checkers['func'] = exports.checkers['function'];
exports.checkers['obj'] = exports.checkers['object'];
exports.checkers.func = exports.checkers.function;
exports.checkers.obj = exports.checkers.object;
exports.checkers['obj+'] = exports.checkers['object+'];
exports.checkers['arr'] = exports.checkers['array'];
exports.checkers.arr = exports.checkers.array;
exports.checkers['arr+'] = exports.checkers['array+'];
exports.checkers['args'] = exports.checkers['arguments'];
exports.checkers.args = exports.checkers.arguments;
//# sourceMappingURL=checkers.js.map
export declare class BlorkError extends Error {
static message: string;
static [Symbol.toStringTag]: string;
message: string;
name: string;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class BlorkError extends Error {
constructor() {
super(...arguments);
this.message = 'Invalid configuration';
this.name = BlorkError.name;
}
}
BlorkError.message = "Blork: You're using it wrong!";
BlorkError[Symbol.toStringTag] = 'BlorkError';
BlorkError[Symbol.toStringTag] = BlorkError.name;
exports.BlorkError = BlorkError;
//# sourceMappingURL=errors.js.map

@@ -1,2 +0,2 @@

export declare function debug(value: any): any;
export declare function format(message: string, value: any, prefix?: string): string;
export declare function debug(value: any): string;
export declare function format(message: string, value?: any, prefix?: string): string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const UNDEF = Symbol();
function debug(value) {
switch (value) {
case null: return 'null';
case undefined: return 'undefined';
case true: return 'true';
case false: return 'false';
default: switch (typeof value) {
case 'string': return JSON.stringify(value.length > 20 ? value.substr(0, 20) + '…' : value);
case 'number': return value.toString();
case 'function': return value.name ? 'function ' + value.name + '()' : 'anonymous function';
case 'object': switch (value.constructor) {
case Object:
const l = Object.keys(value).length;
l ? 'object {} with ' + l + ' props' : 'empty object';
case Array: return value.length ? 'Array with ' + value.length + ' items' : 'empty array';
case Map:
case Set: return value.size ? 'empty ' + value.constructor.name : value.constructor.name + ' with ' + value.size + ' items';
default: return value.constructor.name ? 'instance of ' + value.constructor.name : 'instance of anonymous class';
if (value === null)
return 'null';
if (value === undefined)
return 'undefined';
if (value === true)
return 'true';
if (value === false)
return 'false';
if (typeof value === 'string') {
const max = 20;
return JSON.stringify(value.length > max ? `${value.substr(0, max)}…` : value);
}
if (typeof value === 'number')
return value.toString();
if (typeof value === 'symbol')
return value.toString();
if (value instanceof Function) {
if (value.name.length > 0)
return `function ${value.name}()`;
return 'anonymous function';
}
if (value instanceof Array)
return value.length > 0 ? `${value.constructor.name} with ${value.length} items` : `empty ${value.constructor.name}`;
if (value instanceof Object) {
if (value.constructor instanceof Function && value.constructor.name.length > 0) {
if (value.constructor === Object) {
const l = Object.keys(value).length;
return l > 0 ? `Object with ${l} props` : 'empty Object';
}
return `instance of ${value.constructor.name}`;
}
return 'instance of anonymous class';
}
return 'unknown value';
}
exports.debug = debug;
function format(message, value, prefix) {
return (prefix ? prefix + ': ' : '') + message + (typeof value !== undefined ? ' (received ' + debug(value) + ')' : '');
function format(message, value = UNDEF, prefix) {
const debugged = debug(value);
return (typeof prefix === 'string' && prefix.length > 0 ? `${prefix}: ` : '') + message + (value !== UNDEF ? ` (received ${debugged})` : '');
}
exports.format = format;
//# sourceMappingURL=helpers.js.map

@@ -1,6 +0,12 @@

export interface CheckerFunction {
(v: any): true | string;
export declare type Types = string | TypeFunction | TypesArray | TypesObject;
export declare type TypeFunction = () => void;
export interface TypesArray extends Array<Types> {
}
export interface TypesObject {
[key: string]: Types;
}
export declare type CheckerReturns = true | string;
export declare type CheckerFunction = (v: any) => CheckerReturns;
export interface ErrorConstructor {
new (message: string): Object;
new (message: string): object;
}

@@ -11,6 +17,1 @@ export interface ArgumentsObject {

}
export interface TypesArray extends Array<string | Function | TypesObject | TypesArray> {
}
export interface TypesObject {
[key: string]: string | Function | TypesArray | TypesObject;
}
{
"name": "blork",
"description": "Blork! Mini (non-static) argument checking in Javascript",
"version": "1.0.0",
"version": "1.1.0",
"license": "0BSD",

@@ -15,10 +15,16 @@ "author": "Dave Houlbrooke <dave@shax.com>",

"devDependencies": {
"jest": "latest",
"husky": "latest",
"typescript": "latest",
"@types/node": "latest",
"eslint": "latest",
"typescript": "latest"
"tslint": "latest",
"jest": "latest"
},
"scripts": {
"fix": "tslint -p tsconfig.json --fix",
"prebuild": "npm run fix",
"build": "rm -rf lib && mkdir lib && tsc -p tsconfig.json",
"pretest": "npm run build",
"test": "jest",
"watch": "jest --watchAll"
"watch": "jest --watchAll",
"precommit": "npm run build && npm run test"
},

@@ -25,0 +31,0 @@ "repository": {

@@ -120,3 +120,3 @@ # Blork! Mini (non-static) argument checking in Javascript

return typeof v === 'string' && v.indexOf('cat') >= 0 || "Must be a string containing 'cat'";
}
});

@@ -190,3 +190,3 @@ // Check some strings with your checker.

- `'set+'` — An instance of **Set** with one or more items
- `'weakset'` — An instance of **WeakSet*
- `'weakset'` — An instance of **WeakSet**
- `'arguments'` or `'args'` — An **arguments** object (i.e. an object with a numeric **length** property, not an array)

@@ -203,3 +203,3 @@ - `'promise'` — An instance of **Promise**

check(100, 'whole'); // Returns 1
check([1,2,3], 'array+'); // Returns 1
check([1, 2, 3], 'array+'); // Returns 1
check(new Date(2180, 1, 1), 'future'); // Returns 1

@@ -206,0 +206,0 @@

/**
* Blork!
* Mini non-static type checking in Javascript.
* Blork! Main file
*
* Exports functions for other modules to access.
* Exported functions must validate their arguments (we don't know how they'll be used).
*
* @author Dave Houlbrooke <dave@shax.com
*/
import { CheckerFunction, ArgumentsObject, TypesArray, TypesObject, ErrorConstructor } from './types';
import { CheckerFunction, ArgumentsObject, Types, TypesArray, ErrorConstructor } from './types';
import { internalCheck, internalCheckString } from './internal';
import { checkers } from './checkers';

@@ -13,207 +16,91 @@ import { format } from './helpers';

// Vars.
let errorConstructor:ErrorConstructor = TypeError;
let errorConstructor: ErrorConstructor = TypeError;
// Public functions.
/**
* Check values against types.
* Throws an error if a value doesn't match a specified type.
*
* @param values A single value (or object/array with values) to check against the type(s).
* @param type A single stringy type reference (e.g. 'str'), functional shorthand type reference (e.g. `String`), or an object/array with list of types (e.g. `{name:'str'}` or `['str', 'num']`).
* @param prefix='' Prefix for error messages, to assist debugging.
*
* @return Returns the number of values that passed their checks.
* @throws An error describing what went wrong (usually an error object).
*/
export function check(value: any, type: Types, prefix = '') { // tslint:disable-line:no-any
/**
* Check values against types.
* Throws an error if a value doesn't match a specified type.
*
* @param {mixed|object} value A single value (or object/array with values) to check against the type(s).
* @param {string|object} type A single stringy type reference (e.g. 'str'), functional shorthand type reference (e.g. `String`), or an object/array with list of types (e.g. `{name:'str'}` or `['str', 'num']`).
* @param {string} prefix='' Prefix for error messages, to assist debugging.
*
* @return {integer} Returns the number of values that passed their checks.
* @throws {mixed} An error describing what went wrong (usually an error object).
*/
export function check(value:any, type:any, prefix:string = '')
{
// Check args.
safe(prefix, 'string', 'arguments[2]', BlorkError);
// Check args.
internalCheck(prefix, 'string', 'arguments[2]', BlorkError);
// Check the value against the type.
return safe(value, type, prefix, errorConstructor);
}
// Check the value against the type.
return internalCheck(value, type, prefix, errorConstructor);
/**
* Check function arguments against types.
* Same as check() but slightly friendlier
*
* @param {object} args The entire arguments object from the function call. Must have a .length property.
* @param {array} types A set of types corresponding to the argument.
*
* @return {integer} Returns the number of values that passed their checks.
* @throws {mixed} An error describing what went wrong (usually an error object).
*/
export function args(args:ArgumentsObject, types:TypesArray)
{
// Check args.
safe(args, 'args', 'arguments[0]', BlorkError);
safe(types, 'array', 'arguments[1]', BlorkError);
}
// Vars.
let pass = 0;
const l = types.length;
/**
* Check function arguments against types.
* Same as check() but slightly friendlier
*
* @param argsObj The entire arguments object from the function call. Must have a .length property.
* @param types A set of types corresponding to the argument.
*
* @return Returns the number of values that passed their checks.
* @throws An error describing what went wrong (usually an error object).
*/
export function args(argsObj: ArgumentsObject, types: TypesArray) {
// Loop through types and recurse into each.
for (let i = 0; i < l; i++) if (safe(args[i], types[i], 'arguments[' + i + ']', errorConstructor)) pass++;
// Check args.
internalCheckString(argsObj, 'args', 'arguments[0]', BlorkError);
internalCheckString(types, 'array', 'arguments[1]', BlorkError);
// No excess arguments.
if (args.length > l) throw new errorConstructor(format('Must not have more than ' + l + ' arguments', args.length, 'arguments'));
// Vars.
const l = types.length;
let pass = 0;
// Success.
return pass;
}
// Recurse into each type.
for (let i = 0; i < l; i++) if (internalCheck(argsObj[i], types[i], `arguments[${i}]`, errorConstructor)) pass++;
/**
* Add a new custom checker.
*
* Checker function should take in a value, check it and return either `true` (success) or a string error (e.g. `Must be a whole number`).
* This format is chosen because it allows buttery constructions like `check.add(const str = v => (typeof v === 'string' || 'must be string');
*
* @param {string} name The type reference for the checker.
* @param {function} checker A checker function: Takes a single argument (value), tests it, and returns either true (success) or an error message string in the 'Must be X' format.
* @return {void}
*/
export function add(name:string, checker:CheckerFunction)
{
// Check args.
safe(name, 'lower+', 'arguments[0]', BlorkError);
safe(checker, 'function', 'arguments[1]', BlorkError);
// No excess arguments.
if (argsObj.length > l) { throw new errorConstructor(format(`Must not have more than ${l} arguments`, argsObj.length, 'arguments')); }
// Don't double up.
if (checkers[name]) throw new BlorkError("Checker '" + name + " already exists");
// Success.
return pass;
// Save the checker.
checkers[name] = checker;
}
}
/**
* Set the error any failed checks should throw.
*
* @param {function} err The error constructor to use for
* @return {void}
*/
export function throws(err:ErrorConstructor)
{
// Check args.
safe(err, 'function', 'arguments[0]', BlorkError);
/**
* Add a new custom checker.
*
* Checker function should take in a value, check it and return either `true` (success) or a string error (e.g. `Must be a whole number`).
* This format is chosen because it allows buttery constructions like `check.add(const str = v => (typeof v === 'string' || 'must be string');
*
* @param name The type reference for the checker.
* @param checker A checker function: Takes a single argument (value), tests it, and returns either true (success) or an error message string in the 'Must be X' format.
*/
export function add(name: string, checker: CheckerFunction) {
// Save errorConstructor.
errorConstructor = err;
}
// Check args.
internalCheckString(name, 'lower+', 'arguments[0]', BlorkError);
internalCheckString(checker, 'function', 'arguments[1]', BlorkError);
// Internal.
// Don't double up.
if (checkers[name]) { throw new BlorkError(`Blork type '${name}' already exists`); }
/**
* Internal check.
* Called safe because it's only used internally, so arguments aren't typechecked.
*
* @param {mixed|object} value A single value (or object/array with values) to check against the type(s).
* @param {string|object} type A single stringy type reference (e.g. 'str'), functional shorthand type reference (e.g. `String`), or an object/array with list of types (e.g. `{name:'str'}` or `['str', 'num']`).
* @param {string} name Name of the value (prefixed to error messages to assist debugging).
* @param {function} errorConstructor Type of error that gets thrown if values don't match types.
*
* @return {integer} Returns the number of values that passed their checks.
* @throws {mixed} An error describing what went wrong (usually an error object).
*
* @internal
*/
function safe(value:any, type:string|Function|TypesArray|TypesObject, name:string, errorConstructor:ErrorConstructor)
{
// If it's a plain object or plain array, we're checking a set of values.
if (typeof type === 'string')
{
// Find checker in list of checkers.
let checker = checkers[type];
if (!checker)
{
// Optional value (ends with '?')
if (type.length && type[type.length - 1] === '?')
{
// Find checker without '?'.
checker = checkers[type.slice(0, -1)];
// Save the checker.
checkers[name] = checker;
// Undefined.
if (checker && value === undefined) return 0;
}
}
// Unknown checker.
if (!checker) throw new BlorkError("Checker '" + type + "' does not exist");
}
/**
* Set the error any failed checks should throw.
* @param err The error constructor to use for
*/
export function throws(err: ErrorConstructor) {
// Check, and error if it fails.
const result = checker(value);
// Check args.
internalCheckString(err, 'function', 'arguments[0]', BlorkError);
// Success if it returned true, Error if it returned string.
if (result === true) return 1;
else if (typeof result === 'string') throw new errorConstructor(format(result, value, name));
else throw new BlorkError(format("Checker '" + type + "' did not return true or string", result));
}
else if (type instanceof Function)
{
// Vars.
let result:string|true = true;
// Save errorConstructor.
errorConstructor = err;
// Switch for type.
switch (type)
{
// Built-in types.
case Boolean: result = checkers.bool(value); break;
case Number: result = checkers.num(value); break;
case String: result = checkers.str(value); break;
case Object: result = checkers.obj(value); break;
// Other types do an instanceof check.
default: if (!(value instanceof type)) result = 'Must be instance of ' + (type.name || 'specified object');
}
// Success if it returned true, Error if it returned string.
if (typeof result === 'string') throw new errorConstructor(format(result, value, name));
else return 1; // We trust our builtin checkers not to return anything else, so assume success.
}
else if (type instanceof Array)
{
// Value must be an array.
safe(value, 'array', name, errorConstructor);
// Vars.
if (!name.length) name = 'Array';
let pass = 0;
// Tuple array or normal array.
if (type.length === 1)
{
// Normal array: Loop through items and check they match type[0]
const l = value.length;
for (let i = 0; i < l; i++) if (safe(value[i], type[0], name + '[' + i + ']', errorConstructor)) pass++;
}
else
{
// Tuple array: Loop through types and match each with a value recursively.
const l = type.length;
for (let i = 0; i < l; i++) if (safe(value[i], type[i], name + '[' + i + ']', errorConstructor)) pass++;
// No excess items in a tuple.
if (value.length > l) throw new errorConstructor(format('Must not have more than ' + l + ' array items', value.length, name));
}
// Success!
return pass;
}
else if (type instanceof Object)
{
// Value must be an object.
safe(value, 'object', name, errorConstructor);
// Vars.
let pass = 0;
// Loop through types and recurse into each.
for (const key in type) if (safe(value[key], type[key], (name ? name + '[' + key + ']' : key), errorConstructor)) pass++;
// Success!
return pass;
}
else throw new BlorkError(format('Checker type must be a string, function, array, or object', type));
}
}

@@ -0,61 +1,69 @@

/**
* Blork! Built-in checkers
* List of built-in checkers indexed by string type name. Some checkers have duplicate names.
*
* @author Dave Houlbrooke <dave@shax.com
*/
import { CheckerFunction } from './types';
// Checker functions.
export const checkers:{[key:string]:CheckerFunction} = {
'null': (v:any) => v === null || 'Must be null',
'undefined': (v:any) => v === undefined || 'Must be undefined',
'defined': (v:any) => v !== undefined || 'Must be defined',
'boolean': (v:any) => (v === true || v === false) || 'Must be true or false',
'true': (v:any) => v === true || 'Must be true',
'false': (v:any) => v === false || 'Must be false',
'truthy': (v:any) => !!v || 'Must be truthy',
'falsy': (v:any) => !v || 'Must be falsy',
'number': (v:any) => typeof v === 'number' || 'Must be number',
'integer': (v:any) => Number.isInteger(v) && v >= Number.MIN_SAFE_INTEGER && v <= Number.MAX_SAFE_INTEGER || 'Must be an integer',
'natural': (v:any) => Number.isInteger(v) && v > 0 && v <= Number.MAX_SAFE_INTEGER || 'Must be a natural number, e.g. 1, 2, 3',
'whole': (v:any) => Number.isInteger(v) && v >= 0 && v <= Number.MAX_SAFE_INTEGER || 'Must be a whole number, e.g. 0, 1, 2, 3',
'finite': (v:any) => Number.isFinite(v) || 'Must be a finite number',
'string': (v:any) => typeof v === 'string' || 'Must be a string',
'string+': (v:any) => typeof v === 'string' && v.length > 0 || 'Must be a non-empty string',
'lowercase': (v:any) => typeof v === 'string' && v === v.toLowerCase() || 'Must be a lowercase string',
'lowercase+': (v:any) => typeof v === 'string' && v.length > 0 && v === v.toLowerCase() || 'Must be a non-empty lowercase string',
'uppercase': (v:any) => typeof v === 'string' && v === v.toUpperCase() || 'Must be an uppercase string',
'uppercase+': (v:any) => typeof v === 'string' && v.length > 0 && v === v.toUpperCase() || 'Must be a non-empty uppercase string',
'function': (v:any) => v instanceof Function || 'Must be an function',
'object': (v:any) => v instanceof Object || 'Must be an object',
'object+': (v:any) => v instanceof Object && Object.keys(v).length > 0 || 'Must be an object with one or more enumerable properties',
'iterable': (v:any) => v instanceof Object && typeof v[Symbol.iterator] === 'function' || 'Must be an iterable object',
'array': (v:any) => v instanceof Array || 'Must be an array',
'array+': (v:any) => v instanceof Array && v.length > 0 || 'Must be a non-empty array',
'map': (v:any) => v instanceof Map || 'Must be a map',
'map+': (v:any) => v instanceof Map && v.size > 0 || 'Must be a non-empty map',
'weakmap': (v:any) => v instanceof WeakMap || 'Must be a weak map',
'set': (v:any) => v instanceof Set || 'Must be a set',
'set+': (v:any) => v instanceof Set && v.size > 0 || 'Must be a non-empty set',
'weakset': (v:any) => v instanceof WeakSet || 'Must be a weak set',
'arguments': (v:any) => v instanceof Object && typeof v.length === 'number' || 'Must be an arguments object',
'promise': (v:any) => v instanceof Promise || 'Must be a promise',
'date': (v:any) => v instanceof Date || 'Must be a date',
'future': (v:any) => v instanceof Date && v.getTime() > Date.now() || 'Must be a date in the future',
'past': (v:any) => v instanceof Date && v.getTime() < Date.now() || 'Must be a date in the past',
// tslint:disable:no-any no-unsafe-any
export const checkers: { [key: string]: CheckerFunction } = {
'null': (v: any) => v === null || 'Must be null',
'undefined': (v: any) => v === undefined || 'Must be undefined',
'defined': (v: any) => v !== undefined || 'Must be defined',
'boolean': (v: any) => v === true || v === false || 'Must be true or false',
'true': (v: any) => v === true || 'Must be true',
'false': (v: any) => v === false || 'Must be false',
'truthy': (v: any) => !!v || 'Must be truthy',
'falsy': (v: any) => !v || 'Must be falsy',
'number': (v: any) => typeof v === 'number' || 'Must be number',
'integer': (v: any) => (typeof v === 'number' && Number.isInteger(v) && v >= Number.MIN_SAFE_INTEGER && v <= Number.MAX_SAFE_INTEGER) || 'Must be an integer',
'natural': (v: any) => (typeof v === 'number' && Number.isInteger(v) && v > 0 && v <= Number.MAX_SAFE_INTEGER) || 'Must be a natural number, e.g. 1, 2, 3',
'whole': (v: any) => (typeof v === 'number' && Number.isInteger(v) && v >= 0 && v <= Number.MAX_SAFE_INTEGER) || 'Must be a whole number, e.g. 0, 1, 2, 3',
'finite': (v: any) => (typeof v === 'number' && Number.isFinite(v)) || 'Must be a finite number',
'string': (v: any) => typeof v === 'string' || 'Must be a string',
'string+': (v: any) => (typeof v === 'string' && v.length > 0) || 'Must be a non-empty string',
'lowercase': (v: any) => (typeof v === 'string' && v === v.toLowerCase()) || 'Must be a lowercase string',
'lowercase+': (v: any) => (typeof v === 'string' && v.length > 0 && v === v.toLowerCase()) || 'Must be a non-empty lowercase string',
'uppercase': (v: any) => (typeof v === 'string' && v === v.toUpperCase()) || 'Must be an uppercase string',
'uppercase+': (v: any) => (typeof v === 'string' && v.length > 0 && v === v.toUpperCase()) || 'Must be a non-empty uppercase string',
'function': (v: any) => v instanceof Function || 'Must be an function',
'object': (v: any) => (typeof v === 'object' && v !== null) || 'Must be an object',
'object+': (v: any) => (typeof v === 'object' && v !== null && Object.keys(v).length > 0) || 'Must be an object with one or more enumerable properties',
'iterable': (v: any) => (typeof v === 'object' && v !== null && typeof v[Symbol.iterator] === 'function') || 'Must be an iterable object', // tslint:disable-line:no-any
'array': (v: any) => v instanceof Array || 'Must be an array',
'array+': (v: any) => (v instanceof Array && v.length > 0) || 'Must be a non-empty array',
'map': (v: any) => v instanceof Map || 'Must be a map',
'map+': (v: any) => (v instanceof Map && v.size > 0) || 'Must be a non-empty map',
'weakmap': (v: any) => v instanceof WeakMap || 'Must be a weak map',
'set': (v: any) => v instanceof Set || 'Must be a set',
'set+': (v: any) => (v instanceof Set && v.size > 0) || 'Must be a non-empty set',
'weakset': (v: any) => v instanceof WeakSet || 'Must be a weak set',
'arguments': (v: any) => (typeof v === 'object' && v !== null && v.hasOwnProperty('length') && typeof v.length === 'number') || 'Must be an arguments object',
'promise': (v: any) => v instanceof Promise || 'Must be a promise',
'date': (v: any) => v instanceof Date || 'Must be a date',
'future': (v: any) => (v instanceof Date && v.getTime() > Date.now()) || 'Must be a date in the future',
'past': (v: any) => (v instanceof Date && v.getTime() < Date.now()) || 'Must be a date in the past',
};
// tslint:enable:no-any no-unsafe-any
// Checker alternates.
checkers['void'] = checkers['undefined'];
checkers['undef'] = checkers['undefined'];
checkers['def'] = checkers['defined'];
checkers['bool'] = checkers['boolean'];
checkers['num'] = checkers['number'];
checkers['int'] = checkers['integer'];
checkers['str'] = checkers['string'];
checkers.void = checkers.undefined;
checkers.undef = checkers.undefined;
checkers.def = checkers.defined;
checkers.bool = checkers.boolean;
checkers.num = checkers.number;
checkers.int = checkers.integer;
checkers.str = checkers.string;
checkers['str+'] = checkers['string+'];
checkers['lower'] = checkers['lowercase'];
checkers.lower = checkers.lowercase;
checkers['lower+'] = checkers['lowercase+'];
checkers['upper'] = checkers['uppercase'];
checkers.upper = checkers.uppercase;
checkers['upper+'] = checkers['uppercase+'];
checkers['func'] = checkers['function'];
checkers['obj'] = checkers['object'];
checkers.func = checkers.function;
checkers.obj = checkers.object;
checkers['obj+'] = checkers['object+'];
checkers['arr'] = checkers['array'];
checkers.arr = checkers.array;
checkers['arr+'] = checkers['array+'];
checkers['args'] = checkers['arguments'];
checkers.args = checkers.arguments;

@@ -1,8 +0,24 @@

"use strict";
/**
* Blork! Error types
* @author Dave Houlbrooke <dave@shax.com
*/
// An issue with the way the user is calling Blork.
export class BlorkError extends Error
{
static message = "Blork: You're using it wrong!";
static [Symbol.toStringTag] = 'BlorkError';
}
/**
* BlorkError
*
* Blork normally throws TypeError (or a custom error) when the value you're checking is invalid.
* But! A BlorkError is thrown when you're using Blork wrong.
* - The type you're checking against (not the value you're checking) is invalid or doesn't exist.
*/
export class BlorkError extends Error {
// Makes the object appear like [object BlorkError] instead of [object Error]
public static [Symbol.toStringTag] = BlorkError.name;
/** Error message. */
public message = 'Invalid configuration';
/** Error name */
public name = BlorkError.name;
}

@@ -1,39 +0,67 @@

import { CheckerFunction } from './types';
/**
* Blork! Helper functions
* @author Dave Houlbrooke <dave@shax.com
*/
// Vars.
const UNDEF = Symbol();
/**
* Neatly convert any value into a string for debugging.
*
* @param {mixed} value The value to convert to a string.
* @return {string} The value after it has been converted to a string.
* @param value The value to convert to a string.
* @return The value after it has been converted to a string.
*/
export function debug(value: any)
{
switch (value)
{
case null: return 'null';
case undefined: return 'undefined';
case true: return 'true';
case false: return 'false';
default: switch (typeof value)
{
case 'string': return JSON.stringify(value.length > 20 ? value.substr(0, 20) + '…' : value); // e.g. "You can \"quote me\" on that"
case 'number': return value.toString(); // e.g. 123 or 456.789
case 'function': return value.name ? 'function ' + value.name + '()' : 'anonymous function';
case 'object': switch (value.constructor)
{
case Object: const l = Object.keys(value).length; l ? 'object {} with ' + l + ' props' : 'empty object';
case Array: return value.length ? 'Array with ' + value.length + ' items' : 'empty array';
case Map: case Set: return value.size ? 'empty ' + value.constructor.name : value.constructor.name + ' with ' + value.size + ' items';
default: return value.constructor.name ? 'instance of ' + value.constructor.name : 'instance of anonymous class';
export function debug(value: any) { // tslint:disable-line:no-any
if (value === null) return 'null';
if (value === undefined) return 'undefined';
if (value === true) return 'true';
if (value === false) return 'false';
if (typeof value === 'string') {
const max = 20;
return JSON.stringify(value.length > max ? `${value.substr(0, max)}…` : value);
}
if (typeof value === 'number') return value.toString(); // E.g. 123 or 456.789
if (typeof value === 'symbol') return value.toString(); // E.g. Symbol(foo)
if (value instanceof Function) {
// tslint:disable:no-unsafe-any
if (value.name.length > 0) return `function ${value.name}()`;
// tslint:enable:no-unsafe-any
return 'anonymous function';
}
if (value instanceof Array) return value.length > 0 ? `${value.constructor.name} with ${value.length} items` : `empty ${value.constructor.name}`;
if (value instanceof Object) {
// tslint:disable:no-unsafe-any
if (value.constructor instanceof Function && value.constructor.name.length > 0) {
if (value.constructor === Object) {
const l = Object.keys(value).length;
return l > 0 ? `Object with ${l} props` : 'empty Object';
}
return `instance of ${value.constructor.name}`;
}
// tslint:enable:no-unsafe-any
return 'instance of anonymous class';
}
return 'unknown value';
}
// Format an error message.
// Optionally with a prefix and a variable to debug.
export function format(message:string, value:any, prefix?:string):string
{
// Something like 'prefix must be string (received 123)
return (prefix ? prefix + ': ' : '') + message + (typeof value !== undefined ? ' (received ' + debug(value) + ')' : '');
}
/**
* Format an error message.
* Optionally with a prefix and a variable to debug.
*
* @param message Message describing what went wrong, e.g. "Must be a string"
* @param value A value to debug shown at the end of the message, e.g. "Must be string (received 123)"
* @param prefix=undefined An optional prefix for the message e.g. the function name or the name of the value, e.g. "name: Must be string (received 123)"
* @returns The error message.
*/
export function format(message: string, value: any = UNDEF, prefix?: string) { // tslint:disable-line:no-any
// Debug the value.
const debugged = debug(value);
// E.g. MyPrefix: Must be string (received 123)
return (typeof prefix === 'string' && prefix.length > 0 ? `${prefix}: ` : '') + message + (value !== UNDEF ? ` (received ${debugged})` : '');
}

@@ -1,28 +0,30 @@

// Checker function interface.
// A function that must return true or string.
export interface CheckerFunction {
(v:any): true|string;
}
/**
* Blork! Typescript types
* @author Dave Houlbrooke <dave@shax.com
*/
// An error constructor.
// A constructor function that must accept string message (and return/generate any object).
export interface ErrorConstructor {
new (message:string): Object;
}
// Types.
// Arguments object interface.
// An object (not an array) that has a numeric length property and string keys with any values.
export interface ArgumentsObject {
[key:string]: any;
length: number;
}
// Types can be string, function, array, or object.
export type Types = string | TypeFunction | TypesArray | TypesObject;
export type TypeFunction = () => void;
export interface TypesArray extends Array<Types> {}
export interface TypesObject { [key: string]: Types; }
// A list of types.
// An array that can contain strings ('bool'), functions (Boolean), or other nested TypesObjects or TypesArrays.
export interface TypesArray extends Array<string|Function|TypesObject|TypesArray> {}
// Checkers.
// A set of named types.
// An object with string keys that can contain strings ('bool'), functions (Boolean), or other nested TypesObjects or TypesArrays.
export interface TypesObject {
[key:string]: string|Function|TypesArray|TypesObject;
}
// Checkers can return true or string.
export type CheckerReturns = true | string;
// Checker function interface.
export type CheckerFunction = (v: any) => CheckerReturns; // tslint:disable-line:no-any
// Other.
// An error constructor.
// A constructor function that must accept string message (and return/generate any object).
export interface ErrorConstructor { new (message: string): object; }
// Arguments object interface.
// An object (not an array) that has a numeric length property and string keys with any values.
export interface ArgumentsObject { [key: string]: any; length: number; } // tslint:disable-line:no-any

@@ -33,17 +33,17 @@ const { BlorkError } = require('../lib/errors');

expect(check('A', 'uppercase+')).toBe(1);
expect(check(function () {}, 'function')).toBe(1);
expect(check({a:1}, 'object')).toBe(1);
expect(check({a:1}, 'object+')).toBe(1);
expect(check(function() {}, 'function')).toBe(1);
expect(check({ a: 1 }, 'object')).toBe(1);
expect(check({ a: 1 }, 'object+')).toBe(1);
expect(check({ [Symbol.iterator]: () => {} }, 'iterable')).toBe(1);
expect(check([], 'array')).toBe(1);
expect(check([1], 'array+')).toBe(1);
expect(check(new Map, 'map')).toBe(1);
expect(check(new Map([[1,1]]), 'map+')).toBe(1)
expect(check(new WeakMap, 'weakmap')).toBe(1)
expect(check(new Set, 'set')).toBe(1)
expect(check(new Map(), 'map')).toBe(1);
expect(check(new Map([[1, 1]]), 'map+')).toBe(1);
expect(check(new WeakMap(), 'weakmap')).toBe(1);
expect(check(new Set(), 'set')).toBe(1);
expect(check(new Set([1]), 'set+')).toBe(1);
expect(check(new WeakSet, 'weakset')).toBe(1);
expect(check(new WeakSet(), 'weakset')).toBe(1);
expect(check(arguments, 'arguments')).toBe(1);
expect(check(Promise.resolve(), 'promise')).toBe(1);
expect(check(new Date, 'date')).toBe(1);
expect(check(new Date(), 'date')).toBe(1);
expect(check(new Date(2080, 0, 1), 'future')).toBe(1);

@@ -60,3 +60,3 @@ expect(check(new Date(1980, 0, 1), 'past')).toBe(1);

expect(check('a', 'str+')).toBe(1);
expect(check(function () {}, 'func')).toBe(1);
expect(check(function() {}, 'func')).toBe(1);
expect(check('a', 'lower')).toBe(1);

@@ -66,4 +66,4 @@ expect(check('a', 'lower+')).toBe(1);

expect(check('A', 'upper+')).toBe(1);
expect(check({a:1}, 'obj')).toBe(1);
expect(check({a:1}, 'obj+')).toBe(1);
expect(check({ a: 1 }, 'obj')).toBe(1);
expect(check({ a: 1 }, 'obj+')).toBe(1);
expect(check([], 'arr')).toBe(1);

@@ -102,6 +102,6 @@ expect(check([1], 'arr+')).toBe(1);

expect(() => check([], 'map')).toThrow(TypeError);
expect(() => check(new Map, 'map+')).toThrow(TypeError);
expect(() => check(new Map(), 'map+')).toThrow(TypeError);
expect(() => check([], 'weakmap')).toThrow(TypeError);
expect(() => check([], 'set')).toThrow(TypeError);
expect(() => check(new Set, 'set+')).toThrow(TypeError);
expect(() => check(new Set(), 'set+')).toThrow(TypeError);
expect(() => check([], 'weakset')).toThrow(TypeError);

@@ -164,6 +164,6 @@ expect(() => check({}, 'arguments')).toThrow(TypeError);

class MyClass {}
const myClass = new MyClass;
const myClass = new MyClass();
expect(check(myClass, MyClass)).toBe(1);
class MySubClass extends MyClass {}
const mySubClass = new MySubClass;
const mySubClass = new MySubClass();
expect(check(mySubClass, MyClass)).toBe(1);

@@ -182,13 +182,13 @@ });

test('Return correctly when checks pass (array literal format)', () => {
expect(check([1,2,3], [Number])).toBe(3);
expect(check([1, 2, 3], [Number])).toBe(3);
});
test('Throw TypeError when checks fail (array literal format)', () => {
expect(() => check([1,2,'surprisestring'], [Number])).toThrow(TypeError);
expect(() => check([1, 2, 'surprisestring'], [Number])).toThrow(TypeError);
});
test('Return correctly when checks pass (array tuple format)', () => {
expect(check([1,2,3], [Number,Number,Number])).toBe(3);
expect(check([1, 2, 3], [Number, Number, Number])).toBe(3);
});
test('Throw TypeError when checks fail (array tuple format)', () => {
expect(() => check([1,1], [Number,String])).toThrow(TypeError);
expect(() => check([1,'b','excessitem'], [Number,String])).toThrow(TypeError);
expect(() => check([1, 1], [Number, String])).toThrow(TypeError);
expect(() => check([1, 'b', 'excessitem'], [Number, String])).toThrow(TypeError);
});

@@ -208,3 +208,3 @@ test('Throw BlorkError if type is not object, function, or string', () => {

const argsObj = { '0': 'a', '1': 123, '2': true, length: 3 };
expect(args(argsObj, [String,Number,Boolean])).toBe(3);
expect(args(argsObj, [String, Number, Boolean])).toBe(3);
});

@@ -217,3 +217,3 @@ test('Throw TypeError when argument checks fail', () => {

const argsObj = { '0': true, '1': true, '2': true, length: 3 };
expect(() => args(argsObj, [Boolean,Boolean])).toThrow(TypeError);
expect(() => args(argsObj, [Boolean, Boolean])).toThrow(TypeError);
});

@@ -226,3 +226,2 @@ test('Throw BlorkError if passing non-arguments-like object', () => {

test('Add and run a custom checker', () => {
// Define a checker called 'isstring'.

@@ -236,3 +235,2 @@ expect(add('test.checker', v => typeof v === 'string' || 'must be string')).toBeUndefined();

expect(() => check(123, 'test.checker')).toThrow(TypeError);
});

@@ -254,5 +252,4 @@ test('Throw BlorkError if not non-empty lowercase string', () => {

test('Set a custom error object and check it throws', () => {
// Define a custom error.
class MyError extends Error {};
class MyError extends Error {}

@@ -264,3 +261,2 @@ // Set it as the custom error.

expect(() => check(false, 'true')).toThrow(MyError);
});

@@ -272,2 +268,2 @@ test('Throw BlorkError if passing a non-function', () => {

});
});
});
{
"compilerOptions": {
"module": "commonjs",
"compilerOptions": {
"module": "commonjs",
"strict": true,
"removeComments": true,
"preserveConstEnums": true,
"removeComments": true,
"preserveConstEnums": true,
"forceConsistentCasingInFileNames": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"sourceMap": true,
"lib": ["es2017"],
"target": "es2015",
"target": "es6",
"declaration": true,
"outDir": "lib",
"watch": true
},
"outDir": "lib"
},
"compileOnSave": true,
"include": ["src/**/*"]
"include": [
"src/**/*"
]
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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