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

fun-model

Package Overview
Dependencies
Maintainers
1
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fun-model - npm Package Compare versions

Comparing version 5.0.1 to 6.0.0

13

index.js

@@ -5,8 +5,9 @@ "use strict";

}
var s = require('./src/store');
var af = require('./src/actionFactory');
var d = require('./src/debug');
__export(require('./src/store'));
__export(require('./src/actionFactory'));
__export(require('./src/helpers'));
Object.defineProperty(exports, "__esModule", { value: true });
var s = require("./src/store");
var af = require("./src/actionFactory");
var d = require("./src/debug");
__export(require("./src/store"));
__export(require("./src/actionFactory"));
__export(require("./src/helpers"));
exports.bootstrap = function (defaultState, onStateChanged, params) {

@@ -13,0 +14,0 @@ params.debugCallback && d.bootstrap(function (m, p) { return params.debugCallback && params.debugCallback("fun-model -> " + m, p); });

{
"name": "fun-model",
"version": "5.0.1",
"version": "6.0.0",
"description": "fun-model is pure functional implementation of FLUX architecture.",

@@ -15,2 +15,14 @@ "main": "./index.js",

},
"bobril": {
"compilerOptions": {
"declaration": true,
"noImplicitAny": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"strictNullChecks": true
}
},
"keywords": [

@@ -23,5 +35,4 @@ "flux"

},
"devDependencies": {
},
"devDependencies": {},
"license": "MIT"
}
}
"use strict";
var s = require('../src/store');
var tds = require('./todosState');
var af = require('../src/actionFactory');
var d = require('../src/debug');
Object.defineProperty(exports, "__esModule", { value: true });
var s = require("../src/store");
var tds = require("./todosState");
var af = require("../src/actionFactory");
var d = require("../src/debug");
describe('actionFactory', function () {
var debugCallback;
var renderCallback;
beforeEach(function () {
resetStore();
af.bootstrap(null);
renderCallback = jasmine.createSpy('render');
debugCallback = jasmine.createSpy('debugCallback');

@@ -21,5 +24,3 @@ d.bootstrap(debugCallback);

describe('array by cursor factory', function () {
var renderCallback;
beforeEach(function () {
renderCallback = jasmine.createSpy('render');
af.bootstrap(renderCallback);

@@ -59,6 +60,4 @@ });

describe('when action threw during handling and catching have not been enabled', function () {
var renderCallback;
var throwingAction;
beforeEach(function () {
renderCallback = jasmine.createSpy('render');
af.bootstrap(renderCallback, false);

@@ -74,6 +73,4 @@ throwingAction = af.createParamLessAction(NestedCursorTestFixture, function () {

describe('when action threw during handling and catching have been enabled', function () {
var renderCallback;
var throwingAction;
beforeEach(function () {
renderCallback = jasmine.createSpy('render');
af.bootstrap(renderCallback, true);

@@ -162,2 +159,19 @@ throwingAction = af.createParamLessAction(NestedCursorTestFixture, function () {

});
describe('createReplaceAction', function () {
beforeEach(function () {
af.bootstrap(renderCallback, false);
});
it('replaces if the state has not been same', function () {
givenStore(aState('nestedStateValue'));
var testAction = af.createReplaceAction(NestedStateCursorTestFixture);
testAction('newNestedStateValue');
expect(renderCallback).toHaveBeenCalled();
});
it('does not replace the same state', function () {
givenStore(aState('nestedStateValue'));
var testAction = af.createReplaceAction(NestedStateCursorTestFixture);
testAction('nestedStateValue');
expect(renderCallback).not.toHaveBeenCalled();
});
});
describe('createActions', function () {

@@ -205,10 +219,2 @@ describe('when renderCallback has not been set', function () {

});
it('uses action as simple setter when no handler defined', function () {
givenStore(aState('nestedStateValue'));
var testAction = af.createAction(NestedStateCursorTestFixture);
testAction('nestedStateValue');
expect(renderCallback).not.toHaveBeenCalled();
testAction('newNestedStateValue');
expect(renderCallback).toHaveBeenCalled();
});
});

@@ -215,0 +221,0 @@ });

@@ -8,2 +8,3 @@ import * as s from '../src/store';

let debugCallback: d.debugCallbackType
let renderCallback: () => void;

@@ -13,2 +14,3 @@ beforeEach(() => {

af.bootstrap(null);
renderCallback = jasmine.createSpy('render');
debugCallback = jasmine.createSpy('debugCallback');

@@ -27,6 +29,3 @@ d.bootstrap(debugCallback);

describe('array by cursor factory', () => {
let renderCallback: () => void;
beforeEach(() => {
renderCallback = jasmine.createSpy('render');
af.bootstrap(renderCallback);

@@ -78,6 +77,4 @@ });

describe('when action threw during handling and catching have not been enabled', () => {
let renderCallback: () => void;
let throwingAction: af.IParamLessAction;
beforeEach(() => {
renderCallback = jasmine.createSpy('render');
af.bootstrap(renderCallback, false);

@@ -95,6 +92,4 @@ throwingAction = af.createParamLessAction(NestedCursorTestFixture, () => {

describe('when action threw during handling and catching have been enabled', () => {
let renderCallback: () => void;
let throwingAction: af.IParamLessAction;
beforeEach(() => {
renderCallback = jasmine.createSpy('render');
af.bootstrap(renderCallback, true);

@@ -210,2 +205,22 @@ throwingAction = af.createParamLessAction(NestedCursorTestFixture, () => {

describe('createReplaceAction', () => {
beforeEach(() => {
af.bootstrap(renderCallback, false);
});
it('replaces if the state has not been same', () => {
givenStore(aState('nestedStateValue'));
const testAction = af.createReplaceAction<string>(NestedStateCursorTestFixture);
testAction('newNestedStateValue');
expect(renderCallback).toHaveBeenCalled();
});
it('does not replace the same state', () => {
givenStore(aState('nestedStateValue'));
const testAction = af.createReplaceAction<string>(NestedStateCursorTestFixture);
testAction('nestedStateValue');
expect(renderCallback).not.toHaveBeenCalled();
});
})
describe('createActions', () => {

@@ -264,13 +279,2 @@ describe('when renderCallback has not been set', () => {

});
it('uses action as simple setter when no handler defined', () => {
givenStore(aState('nestedStateValue'));
const testAction = af.createAction<string, string>(NestedStateCursorTestFixture);
testAction('nestedStateValue');
expect(renderCallback).not.toHaveBeenCalled();
testAction('newNestedStateValue');
expect(renderCallback).toHaveBeenCalled();
});
});

@@ -277,0 +281,0 @@ });

"use strict";
var h = require('../src/helpers');
Object.defineProperty(exports, "__esModule", { value: true });
var h = require("../src/helpers");
describe('helpers', function () {

@@ -4,0 +5,0 @@ describe('shallowCopy', function () {

"use strict";
var s = require('../src/store');
var tds = require('./todosState');
var d = require('../src/debug');
Object.defineProperty(exports, "__esModule", { value: true });
var s = require("../src/store");
var tds = require("./todosState");
var d = require("../src/debug");
describe('store', function () {

@@ -40,3 +41,2 @@ beforeEach(function () {

it('returns true when value exists in state through cursor', function () {
debugger;
var exists = s.isExistingCursor({ key: 'some.nested.arrayState.0' });

@@ -73,5 +73,10 @@ expect(exists).toBeTruthy();

it('throws if key does not exist', function () {
expect(function () { return s.getState({ key: 'not.existing.key' }); })
.toThrow('State for cursor key (not.existing.key) does not exist.');
expect(function () { return s.getState({ key: 'notExistingKey' }); })
.toThrow('State for cursor key (notExistingKey) does not exist.');
});
it('returns udefined if cursor allows that', function () {
givenStore({ some: { nested: { state: 'value' } } });
var state = s.getState({ key: 'some.nested.optional', isUndefinable: true });
expect(state).toBeUndefined();
});
});

@@ -117,10 +122,15 @@ describe('with booting and dynamic/array cursor', function () {

});
it('creates empty object if cursor has not existing key', function () {
it('throws if cursor has not existing key', function () {
var cursor = { key: 'invalid' };
s.setState(cursor, {});
expect(function () { return s.setState(cursor, {}); })
.toThrow();
});
it('creates empty object if cursor has not existing key if told to', function () {
var cursor = { key: 'invalid' };
s.setState(cursor, {}, true);
expect(s.getState(s.rootCursor)).toEqual({ key: null, 'invalid': {} });
});
it('creates neseted empty objects if cursor has not existing key', function () {
it('creates neseted empty objects if cursor has not existing key if told to', function () {
var cursor = { key: 'not.existing.key' };
s.setState(cursor, {});
s.setState(cursor, {}, true);
expect(s.getState(s.rootCursor)).toEqual({ key: null, 'not': { 'existing': { key: {} } } });

@@ -166,2 +176,8 @@ });

});
it('can replace undefined with correct cursor', function () {
givenStore({ some: { nested: { state: 'value' } } });
s.setState({ key: 'some.nested.optional', isUndefinable: true }, 'newValue');
var newState = s.getState(rootCursorTestFixture);
expect(newState.some.nested.optional).toBe('newValue');
});
});

@@ -168,0 +184,0 @@ describe('with booting and dynamic/array cursor', function () {

@@ -51,3 +51,2 @@ import * as s from '../src/store';

it('returns true when value exists in state through cursor', () => {
debugger;
const exists = s.isExistingCursor({ key: 'some.nested.arrayState.0' });

@@ -96,5 +95,13 @@

it('throws if key does not exist', () => {
expect(() => s.getState<s.IState>({ key: 'not.existing.key' }))
.toThrow('State for cursor key (not.existing.key) does not exist.');
expect(() => s.getState<s.IState>({ key: 'notExistingKey' }))
.toThrow('State for cursor key (notExistingKey) does not exist.');
});
it('returns udefined if cursor allows that', () => {
givenStore({ some: { nested: { state: 'value' } } });
const state = s.getState({ key: 'some.nested.optional', isUndefinable: true });
expect(state).toBeUndefined();
})
});

@@ -108,4 +115,4 @@

it('returns nested state in the array on specified index', () => {
givenTodoStore({
todos: [{ done: false, name: 'First Todo' }, { done: false, name: 'Second Todo' }] ,
givenTodoStore({
todos: [{ done: false, name: 'First Todo' }, { done: false, name: 'Second Todo' }],
nullableNumber: null

@@ -120,3 +127,3 @@ });

it('returns full array when is as last key', () => {
givenTodoStore({
givenTodoStore({
todos: [{ done: false, name: 'First Todo' }],

@@ -148,3 +155,3 @@ nullableNumber: null

key: ''
}
};

@@ -155,12 +162,18 @@ beforeEach(() => {

it('creates empty object if cursor has not existing key', () => {
it('throws if cursor has not existing key', () => {
const cursor = { key: 'invalid' };
s.setState(cursor, {});
expect(() => s.setState(cursor, {}))
.toThrow();
});
it('creates empty object if cursor has not existing key if told to', () => {
const cursor = { key: 'invalid' };
s.setState(cursor, {}, true);
expect(s.getState(s.rootCursor)).toEqual({ key: null, 'invalid': {} });
});
it('creates neseted empty objects if cursor has not existing key', () => {
it('creates neseted empty objects if cursor has not existing key if told to', () => {
const cursor = { key: 'not.existing.key' };
s.setState(cursor, {});
s.setState(cursor, {}, true);

@@ -224,2 +237,11 @@ expect(s.getState(s.rootCursor)).toEqual({ key: null, 'not': { 'existing': { key: {} } } });

});
it('can replace undefined with correct cursor', () => {
givenStore({ some: { nested: { state: 'value' } } });
s.setState({ key: 'some.nested.optional', isUndefinable: true }, 'newValue');
const newState = s.getState(rootCursorTestFixture);
expect(newState.some.nested.optional).toBe('newValue');
});
});

@@ -233,3 +255,3 @@

it('sets nested state into array on specified index', () => {
givenTodoStore({
givenTodoStore({
todos: [{ done: false, name: 'First Todo' }, { done: false, name: 'Second Todo' }],

@@ -245,3 +267,3 @@ nullableNumber: null

it('sets new state into array on specified index', () => {
givenTodoStore({
givenTodoStore({
todos: [{ done: false, name: 'First Todo' }],

@@ -258,3 +280,3 @@ nullableNumber: null

const storedTodos = [{ done: false, name: 'First Todo' }, { done: false, name: 'Second Todo' }];
givenTodoStore({
givenTodoStore({
todos: storedTodos,

@@ -270,3 +292,3 @@ nullableNumber: null

it('sets full array', () => {
givenTodoStore({
givenTodoStore({
todos: [{ done: false, name: 'First Todo' }],

@@ -306,3 +328,3 @@ nullableNumber: null

it('write null to state', () => {
s.setState(s.rootCursor, <tds.ITodosState>{
s.setState(s.rootCursor, <tds.ITodosState>{
todos: [{ done: false, name: 'First Todo' }],

@@ -323,3 +345,2 @@ nullableNumber: 10

function resetStore(withFreezing: boolean = false) {

@@ -334,4 +355,5 @@ s.bootstrap(null, withFreezing);

state: string;
optional?: string;
}
}
};
}

@@ -6,3 +6,3 @@ import * as s from '../src/store';

}
declare var _default: () => ITodosState;
declare const _default: () => ITodosState;
export default _default;

@@ -9,0 +9,0 @@ export interface ITodo {

@@ -11,4 +11,5 @@ import * as s from './store';

export declare type IParamLessActionHandler<TState extends s.IState | null> = (state: TState) => TState;
export declare const createAction: <TState extends s.IState | null, TParams>(cursor: s.ICursor<TState> | s.ICursorFactory<TState, TParams>, handler?: (state: TState, t: TParams) => TState) => IAction<TParams>;
export declare const createParamLessAction: <TState extends s.IState | null>(cursor: s.ICursor<TState>, handler: (state: TState) => TState) => IParamLessAction;
export declare const createAction: <TState extends s.IState | null, TParams>(cursor: s.ICursor<TState> | s.ICursorFactory<TState, TParams>, handler: IActionHandler<TState, TParams>) => IAction<TParams>;
export declare const createReplaceAction: <TState extends s.IState | null>(cursor: s.ICursor<TState> | s.ICursorFactory<TState, TState>) => IAction<TState>;
export declare const createParamLessAction: <TState extends s.IState | null>(cursor: s.ICursor<TState>, handler: IParamLessActionHandler<TState>) => IParamLessAction;
export interface IPair<TState extends s.IState | null, TParam> {

@@ -15,0 +16,0 @@ cursor: s.ICursor<TState>;

"use strict";
var s = require('./store');
var d = require('./debug');
var h = require('./helpers');
Object.defineProperty(exports, "__esModule", { value: true });
var s = require("./store");
var d = require("./debug");
var h = require("./helpers");
var stateChanged = null;

@@ -14,5 +15,3 @@ var exceptionHandling;

};
function defaultHandler(_oldValue, newValue) { return newValue; }
exports.createAction = function (cursor, handler) {
if (handler === void 0) { handler = defaultHandler; }
return (function (params) {

@@ -27,2 +26,12 @@ if (stateChanged === null)

};
exports.createReplaceAction = function (cursor) {
return (function (params) {
if (stateChanged === null)
throw 'Render callback must be set before first usage through bootstrap(defaultState, () => { yourRenderCallback(); }).';
if (changeStateWithQueue(unifyCursor(cursor, params), function (_state) { return params; })) {
stateChanged();
d.log('Rendering invoked...');
}
});
};
exports.createParamLessAction = function (cursor, handler) {

@@ -44,3 +53,3 @@ return (function () {

for (var _i = 0; _i < arguments.length; _i++) {
pairs[_i - 0] = arguments[_i];
pairs[_i] = arguments[_i];
}

@@ -51,3 +60,3 @@ return (function (params) {

var changed = false;
var _loop_1 = function() {
var _loop_1 = function () {
if (pairs.hasOwnProperty(i)) {

@@ -68,3 +77,3 @@ var pair_1 = pairs[i];

for (var _i = 0; _i < arguments.length; _i++) {
pairs[_i - 0] = arguments[_i];
pairs[_i] = arguments[_i];
}

@@ -71,0 +80,0 @@ return (function () {

@@ -29,9 +29,9 @@ import * as s from './store';

function defaultHandler<TValue>(_oldValue: TValue, newValue: TValue) { return newValue; }
const renderCallbackMustBeSetBefore = 'Render callback must be set before first usage through bootstrap(defaultState, () => { yourRenderCallback(); }).';
export const createAction = <TState extends s.IState | null, TParams>(cursor: s.ICursor<TState> | s.ICursorFactory<TState, TParams>, handler: IActionHandler<TState, TParams> = defaultHandler)
export const createAction = <TState extends s.IState | null, TParams>(cursor: s.ICursor<TState> | s.ICursorFactory<TState, TParams>, handler: IActionHandler<TState, TParams>)
: IAction<TParams> => {
return <IAction<TParams>>((params: TParams): void => {
if (stateChanged === null)
throw 'Render callback must be set before first usage through bootstrap(defaultState, () => { yourRenderCallback(); }).';
throw renderCallbackMustBeSetBefore;

@@ -45,2 +45,15 @@ if (changeStateWithQueue(unifyCursor<TState, TParams>(cursor, params), (state) => handler(state, params))) {

export const createReplaceAction = <TState extends s.IState | null>(cursor: s.ICursor<TState> | s.ICursorFactory<TState, TState>)
: IAction<TState> => {
return <IAction<TState>>((params: TState): void => {
if (stateChanged === null)
throw renderCallbackMustBeSetBefore;
if (changeStateWithQueue(unifyCursor<TState, TState>(cursor, params), (_state) => params)) {
stateChanged();
d.log('Rendering invoked...');
}
});
};
export const createParamLessAction = <TState extends s.IState | null>(cursor: s.ICursor<TState>, handler: IParamLessActionHandler<TState>)

@@ -50,3 +63,3 @@ : IParamLessAction => {

if (stateChanged === null)
throw 'Render callback must be set before first usage through bootstrap(defaultState, () => { yourRenderCallback(); }).';
throw renderCallbackMustBeSetBefore;

@@ -72,3 +85,4 @@ if (changeStateWithQueue(cursor, handler)) {

if (stateChanged === null)
throw 'Render callback must be set before first usage through bootstrap(defaultState, () => { yourRenderCallback(); }).';
throw renderCallbackMustBeSetBefore;
let changed = false;

@@ -93,3 +107,3 @@ for (var i in pairs)

if (stateChanged === null)
throw 'Render callback must be set before first usage through bootstrap(defaultState, () => { yourRenderCallback(); }).';
throw renderCallbackMustBeSetBefore;
let changed = false;

@@ -143,2 +157,2 @@ for (var i in pairs)

return true;
}
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.debug = undefined;

@@ -3,0 +4,0 @@ exports.bootstrap = function (debugCallback) {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function shallowCopy(source, callback) {

@@ -3,0 +4,0 @@ if (source instanceof Array) {

export interface IState {
}
export interface ICursor<TState extends IState | null> {
export interface ICursor<TState> {
key: string;
isUndefinable?: boolean;
_?: TState;

@@ -12,4 +13,4 @@ }

export declare const bootstrap: (defaultState: IState | null, withStateFreezing?: boolean | (() => boolean), subStateSeparator?: string) => void;
export declare const isExistingCursor: <TState extends IState | null>(cursor: ICursor<TState>) => boolean;
export declare const getState: <TState extends IState | null>(cursor: ICursor<TState>) => TState;
export declare const setState: <TState extends IState | null>(cursor: ICursor<TState>, updatedState: TState) => void;
export declare const isExistingCursor: <TState>(cursor: ICursor<TState>) => boolean;
export declare const getState: <TState>(cursor: ICursor<TState>) => TState;
export declare const setState: <TState>(cursor: ICursor<TState>, updatedState: TState, canCreateObjectsOnPath?: boolean) => void;
"use strict";
var h = require('./helpers');
var d = require('./debug');
Object.defineProperty(exports, "__esModule", { value: true });
var h = require("./helpers");
var d = require("./debug");
var state = null;

@@ -51,3 +52,3 @@ var stateSeparator = '.';

return innerState;
checkSubstate(innerState, subPath, cursor.key);
checkSubstate(innerState, subPath, path, cursor);
var prop = innerState[subPath];

@@ -64,3 +65,4 @@ return Array.isArray(prop) && path.length > 0

};
exports.setState = function (cursor, updatedState) {
exports.setState = function (cursor, updatedState, canCreateObjectsOnPath) {
if (canCreateObjectsOnPath === void 0) { canCreateObjectsOnPath = false; }
var setInnerState = function (innerState, path) {

@@ -72,3 +74,6 @@ if (path.length === 0)

return updatedState;
createSubstate(innerState, subPath);
if (canCreateObjectsOnPath)
createSubstate(innerState, subPath);
else
checkSubstate(innerState, subPath, path, cursor);
var prop = innerState[subPath];

@@ -99,5 +104,7 @@ var newSubState = null;

};
function checkSubstate(s, subPath, cursorKey) {
function checkSubstate(s, subPath, remainingPath, cursor) {
if (remainingPath.length === 0 && cursor.isUndefinable)
return;
if (s[subPath] === undefined)
throw "State for cursor key (" + cursorKey + ") does not exist.";
throw "State for cursor key (" + cursor.key + ") does not exist.";
}

@@ -104,0 +111,0 @@ function createSubstate(s, subPath) {

@@ -7,4 +7,5 @@ import * as h from './helpers';

export interface ICursor<TState extends IState | null> {
export interface ICursor<TState> {
key: string;
isUndefinable?: boolean;
_?: TState;

@@ -32,3 +33,3 @@ }

export const isExistingCursor = <TState extends IState | null>(cursor: ICursor<TState>): boolean => {
export const isExistingCursor = <TState>(cursor: ICursor<TState>): boolean => {
const hasExistingInnerStateInArray = (innerState: IState[], path: string[]): boolean => {

@@ -62,3 +63,3 @@ const index = Number(path.shift());

export const getState = <TState extends IState | null>(cursor: ICursor<TState>): TState => {
export const getState = <TState>(cursor: ICursor<TState>): TState => {
const getInnerState = (innerState: IState, path: string[]): IState => {

@@ -70,3 +71,3 @@ if (path.length === 0)

return innerState;
checkSubstate(innerState, subPath, cursor.key);
checkSubstate(innerState, subPath, path, cursor);
const prop = (<any>innerState)[subPath];

@@ -86,4 +87,4 @@ return Array.isArray(prop) && path.length > 0

export const setState = <TState extends IState | null>(cursor: ICursor<TState>, updatedState: TState) => {
const setInnerState = <TInnerState extends IState | null>(innerState: TInnerState, path: string[]): TInnerState => {
export const setState = <TState>(cursor: ICursor<TState>, updatedState: TState, canCreateObjectsOnPath = false) => {
const setInnerState = <TInnerState>(innerState: TInnerState, path: string[]): TInnerState => {
if (path.length === 0)

@@ -95,3 +96,6 @@ return <any>updatedState;

createSubstate(innerState, subPath);
if (canCreateObjectsOnPath)
createSubstate(innerState, subPath);
else
checkSubstate(innerState, subPath, path, cursor);
const prop = (<any>innerState)[subPath];

@@ -127,8 +131,10 @@ let newSubState: Object | Array<IState> | null = null;

function checkSubstate<TState extends IState | null>(s: TState, subPath: string, cursorKey: string) {
function checkSubstate<TCurrentState, TTargetState>(s: TCurrentState, subPath: string, remainingPath: string[], cursor: ICursor<TTargetState>) {
if (remainingPath.length === 0 && cursor.isUndefinable)
return;
if ((<any>s)[subPath] === undefined)
throw `State for cursor key (${cursorKey}) does not exist.`;
throw `State for cursor key (${cursor.key}) does not exist.`;
}
function createSubstate<TState extends IState | null>(s: TState, subPath: string) {
function createSubstate<TState>(s: TState, subPath: string) {
if ((<any>s)[subPath] === undefined)

@@ -144,3 +150,3 @@ (<any>s)[subPath] = {};

function isValidCursorKey<TState extends IState | null>(cursor: ICursor<TState>): boolean {
function isValidCursorKey<TState>(cursor: ICursor<TState>): boolean {
if (cursor.key === null)

@@ -147,0 +153,0 @@ throw 'Cursor key cannot be null.';

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