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

redux-starter-kit

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

redux-starter-kit - npm Package Compare versions

Comparing version 0.5.1 to 0.6.0

14

dist/createAction.d.ts

@@ -12,10 +12,16 @@ import { Action } from 'redux';

}
export declare type Diff<T, U> = T extends U ? never : T;
/**
* An action creator that produces actions with a `payload` attribute.
*/
export interface PayloadActionCreator<P = any, T extends string = string> {
(): Action<T>;
(payload: P): PayloadAction<P, T>;
export declare type PayloadActionCreator<P = any, T extends string = string> = {
type: T;
}
} & ([undefined] extends [P] ? {
(payload?: undefined): PayloadAction<undefined, T>;
<PT extends Diff<P, undefined>>(payload?: PT): PayloadAction<PT, T>;
} : [void] extends [P] ? {
(): PayloadAction<undefined, T>;
} : {
<PT extends P>(payload: PT): PayloadAction<PT, T>;
});
/**

@@ -22,0 +28,0 @@ * A utility function to create an action creator for the given action type

import { Reducer } from 'redux';
import { PayloadAction } from './createAction';
import { PayloadAction, PayloadActionCreator } from './createAction';
import { CaseReducers } from './createReducer';
/**
* An action creator atttached to a slice.
*
* @deprecated please use PayloadActionCreator directly
*/
export declare type SliceActionCreator<P> = P extends void ? () => PayloadAction<void> : (payload: P) => PayloadAction<P>;
export declare type SliceActionCreator<P> = PayloadActionCreator<P>;
export interface Slice<S = any, AP extends {

@@ -26,3 +28,3 @@ [key: string]: any;

actions: {
[type in keyof AP]: SliceActionCreator<AP[type]>;
[type in keyof AP]: PayloadActionCreator<AP[type]>;
};

@@ -29,0 +31,0 @@ /**

@@ -61,2 +61,6 @@ 'use strict';

function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
}
function _toConsumableArray(arr) {

@@ -74,2 +78,6 @@ return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();

function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArray(iter) {

@@ -79,2 +87,28 @@ if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);

function _iterableToArrayLimit(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _nonIterableSpread() {

@@ -84,2 +118,6 @@ throw new TypeError("Invalid attempt to spread non-iterable instance");

function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
/**

@@ -119,2 +157,3 @@ * Returns true if the passed value is "plain" object, i.e. an object whose

var isSerializable = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : isPlain;
var getEntries = arguments.length > 3 ? arguments[3] : undefined;
var foundNestedSerializable;

@@ -133,21 +172,43 @@

for (var _i = 0, _Object$keys = Object.keys(value); _i < _Object$keys.length; _i++) {
var property = _Object$keys[_i];
var nestedPath = path.concat(property);
var nestedValue = value[property];
var entries = getEntries != null ? getEntries(value) : Object.entries(value);
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
if (!isSerializable(nestedValue)) {
return {
keyPath: nestedPath.join('.'),
value: nestedValue
};
}
try {
for (var _iterator = entries[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _step$value = _slicedToArray(_step.value, 2),
property = _step$value[0],
nestedValue = _step$value[1];
if (_typeof(nestedValue) === 'object') {
foundNestedSerializable = findNonSerializableValue(nestedValue, nestedPath, isSerializable);
var nestedPath = path.concat(property);
if (foundNestedSerializable) {
return foundNestedSerializable;
if (!isSerializable(nestedValue)) {
return {
keyPath: nestedPath.join('.'),
value: nestedValue
};
}
if (_typeof(nestedValue) === 'object') {
foundNestedSerializable = findNonSerializableValue(nestedValue, nestedPath, isSerializable, getEntries);
if (foundNestedSerializable) {
return foundNestedSerializable;
}
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator["return"] != null) {
_iterator["return"]();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}

@@ -171,7 +232,8 @@

var _options$isSerializab = options.isSerializable,
isSerializable = _options$isSerializab === void 0 ? isPlain : _options$isSerializab;
isSerializable = _options$isSerializab === void 0 ? isPlain : _options$isSerializab,
getEntries = options.getEntries;
return function (storeAPI) {
return function (next) {
return function (action) {
var foundActionNonSerializableValue = findNonSerializableValue(action, [], isSerializable);
var foundActionNonSerializableValue = findNonSerializableValue(action, [], isSerializable, getEntries);

@@ -186,3 +248,3 @@ if (foundActionNonSerializableValue) {

var state = storeAPI.getState();
var foundStateNonSerializableValue = findNonSerializableValue(state);
var foundStateNonSerializableValue = findNonSerializableValue(state, [], isSerializable, getEntries);

@@ -375,2 +437,4 @@ if (foundStateNonSerializableValue) {

* An action creator atttached to a slice.
*
* @deprecated please use PayloadActionCreator directly
*/

@@ -377,0 +441,0 @@

@@ -57,2 +57,6 @@ import { combineReducers, applyMiddleware, createStore, compose } from 'redux';

function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
}
function _toConsumableArray(arr) {

@@ -70,2 +74,6 @@ return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();

function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArray(iter) {

@@ -75,2 +83,28 @@ if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);

function _iterableToArrayLimit(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _nonIterableSpread() {

@@ -80,2 +114,6 @@ throw new TypeError("Invalid attempt to spread non-iterable instance");

function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
/**

@@ -115,2 +153,3 @@ * Returns true if the passed value is "plain" object, i.e. an object whose

var isSerializable = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : isPlain;
var getEntries = arguments.length > 3 ? arguments[3] : undefined;
var foundNestedSerializable;

@@ -129,21 +168,43 @@

for (var _i = 0, _Object$keys = Object.keys(value); _i < _Object$keys.length; _i++) {
var property = _Object$keys[_i];
var nestedPath = path.concat(property);
var nestedValue = value[property];
var entries = getEntries != null ? getEntries(value) : Object.entries(value);
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
if (!isSerializable(nestedValue)) {
return {
keyPath: nestedPath.join('.'),
value: nestedValue
};
}
try {
for (var _iterator = entries[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _step$value = _slicedToArray(_step.value, 2),
property = _step$value[0],
nestedValue = _step$value[1];
if (_typeof(nestedValue) === 'object') {
foundNestedSerializable = findNonSerializableValue(nestedValue, nestedPath, isSerializable);
var nestedPath = path.concat(property);
if (foundNestedSerializable) {
return foundNestedSerializable;
if (!isSerializable(nestedValue)) {
return {
keyPath: nestedPath.join('.'),
value: nestedValue
};
}
if (_typeof(nestedValue) === 'object') {
foundNestedSerializable = findNonSerializableValue(nestedValue, nestedPath, isSerializable, getEntries);
if (foundNestedSerializable) {
return foundNestedSerializable;
}
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator["return"] != null) {
_iterator["return"]();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}

@@ -167,7 +228,8 @@

var _options$isSerializab = options.isSerializable,
isSerializable = _options$isSerializab === void 0 ? isPlain : _options$isSerializab;
isSerializable = _options$isSerializab === void 0 ? isPlain : _options$isSerializab,
getEntries = options.getEntries;
return function (storeAPI) {
return function (next) {
return function (action) {
var foundActionNonSerializableValue = findNonSerializableValue(action, [], isSerializable);
var foundActionNonSerializableValue = findNonSerializableValue(action, [], isSerializable, getEntries);

@@ -182,3 +244,3 @@ if (foundActionNonSerializableValue) {

var state = storeAPI.getState();
var foundStateNonSerializableValue = findNonSerializableValue(state);
var foundStateNonSerializableValue = findNonSerializableValue(state, [], isSerializable, getEntries);

@@ -371,2 +433,4 @@ if (foundStateNonSerializableValue) {

* An action creator atttached to a slice.
*
* @deprecated please use PayloadActionCreator directly
*/

@@ -373,0 +437,0 @@

@@ -14,3 +14,3 @@ import { Middleware } from 'redux';

}
export declare function findNonSerializableValue(value: unknown, path?: ReadonlyArray<string>, isSerializable?: (value: unknown) => boolean): NonSerializableValue | false;
export declare function findNonSerializableValue(value: unknown, path?: ReadonlyArray<string>, isSerializable?: (value: unknown) => boolean, getEntries?: (value: unknown) => [string, any][]): NonSerializableValue | false;
/**

@@ -26,2 +26,8 @@ * Options for `createSerializableStateInvariantMiddleware()`.

isSerializable?: (value: any) => boolean;
/**
* The function that will be used to retrieve entries from each
* value. If unspecified, `Object.entries` will be used. Defaults
* to `undefined`.
*/
getEntries?: (value: any) => [string, any][];
}

@@ -28,0 +34,0 @@ /**

{
"name": "redux-starter-kit",
"version": "0.5.1",
"version": "0.6.0",
"description": "A simple set of tools to make using Redux easier",

@@ -5,0 +5,0 @@ "repository": "https://github.com/markerikson/redux-starter-kit",

@@ -15,10 +15,24 @@ import { Action } from 'redux'

export type Diff<T, U> = T extends U ? never : T;
/**
* An action creator that produces actions with a `payload` attribute.
*/
export interface PayloadActionCreator<P = any, T extends string = string> {
(): Action<T>
(payload: P): PayloadAction<P, T>
type: T
}
export type PayloadActionCreator<P = any, T extends string = string> = { type: T } & (
/*
* The `P` generic is wrapped with a single-element tuple to prevent the
* conditional from being checked distributively, thus preserving unions
* of contra-variant types.
*/
[undefined] extends [P] ? {
(payload?: undefined): PayloadAction<undefined, T>
<PT extends Diff<P, undefined>>(payload?: PT): PayloadAction<PT, T>
}
: [void] extends [P] ? {
(): PayloadAction<undefined, T>
}
: {
<PT extends P>(payload: PT): PayloadAction<PT, T>
}
);

@@ -37,5 +51,3 @@ /**

): PayloadActionCreator<P, T> {
function actionCreator(): Action<T>
function actionCreator(payload: P): PayloadAction<P, T>
function actionCreator(payload?: P): Action<T> | PayloadAction<P, T> {
function actionCreator(payload?: P): PayloadAction<undefined | P, T> {
return { type, payload }

@@ -48,3 +60,3 @@ }

return actionCreator
return actionCreator as any
}

@@ -51,0 +63,0 @@

import { Reducer } from 'redux'
import { createAction, PayloadAction } from './createAction'
import { createAction, PayloadAction, PayloadActionCreator } from './createAction'
import { createReducer, CaseReducers } from './createReducer'

@@ -8,6 +8,6 @@ import { createSliceSelector, createSelectorName } from './sliceSelector'

* An action creator atttached to a slice.
*
* @deprecated please use PayloadActionCreator directly
*/
export type SliceActionCreator<P> = P extends void
? () => PayloadAction<void>
: (payload: P) => PayloadAction<P>
export type SliceActionCreator<P> = PayloadActionCreator<P>

@@ -17,3 +17,3 @@ export interface Slice<

AP extends { [key: string]: any } = { [key: string]: any }
> {
> {
/**

@@ -33,3 +33,3 @@ * The slice name.

*/
actions: { [type in keyof AP]: SliceActionCreator<AP[type]> }
actions: { [type in keyof AP]: PayloadActionCreator<AP[type]> }

@@ -51,3 +51,3 @@ /**

CR extends CaseReducers<S, any> = CaseReducers<S, any>
> {
> {
/**

@@ -81,6 +81,6 @@ * The slice's name. Used to namespace the generated action types and to

[T in keyof CR]: CR[T] extends (state: any) => any
? void
: (CR[T] extends (state: any, action: PayloadAction<infer P>) => any
? P
: void)
? void
: (CR[T] extends (state: any, action: PayloadAction<infer P>) => any
? P
: void)
}

@@ -87,0 +87,0 @@

@@ -6,3 +6,4 @@ import { Reducer } from 'redux'

createSerializableStateInvariantMiddleware,
findNonSerializableValue
findNonSerializableValue,
isPlain,
} from './serializableStateInvariantMiddleware'

@@ -162,2 +163,161 @@

})
describe('consumer tolerated structures', () => {
const nonSerializableValue = new Map();
const nestedSerializableObjectWithBadValue = {
isSerializable: true,
entries: (): [string, any][] =>
[
['good-string', 'Good!'],
['good-number', 1337],
['bad-map-instance', nonSerializableValue],
],
};
const serializableObject = {
isSerializable: true,
entries: (): [string, any][] =>
[
['first', 1],
['second', 'B!'],
['third', nestedSerializableObjectWithBadValue]
],
};
it('Should log an error when a non-serializable value is nested in state', () => {
const ACTION_TYPE = 'TEST_ACTION'
const initialState = {
a: 0
}
const reducer: Reducer = (state = initialState, action) => {
switch (action.type) {
case ACTION_TYPE: {
return {
a: serializableObject
}
}
default:
return state
}
}
// use default options
const serializableStateInvariantMiddleware = createSerializableStateInvariantMiddleware()
const store = configureStore({
reducer: {
testSlice: reducer
},
middleware: [serializableStateInvariantMiddleware]
})
store.dispatch({ type: ACTION_TYPE })
expect(console.error).toHaveBeenCalled()
const [
message,
keyPath,
value,
actionType
] = (console.error as jest.Mock).mock.calls[0]
// since default options are used, the `entries` function in `serializableObject` will cause the error
expect(message).toContain('detected in the state, in the path: `%s`')
expect(keyPath).toBe('testSlice.a.entries')
expect(value).toBe(serializableObject.entries)
expect(actionType).toBe(ACTION_TYPE)
})
it('Should use consumer supplied isSerializable and getEntries options to tolerate certain structures', () => {
const ACTION_TYPE = 'TEST_ACTION'
const initialState = {
a: 0
}
const isSerializable = (val: any): boolean => val.isSerializable || isPlain(val);
const getEntries = (val: any): [string, any][] => val.isSerializable ? val.entries() : Object.entries(val);
const reducer: Reducer = (state = initialState, action) => {
switch (action.type) {
case ACTION_TYPE: {
return {
a: serializableObject
}
}
default:
return state
}
}
const serializableStateInvariantMiddleware = createSerializableStateInvariantMiddleware({ isSerializable, getEntries })
const store = configureStore({
reducer: {
testSlice: reducer
},
middleware: [serializableStateInvariantMiddleware]
})
store.dispatch({ type: ACTION_TYPE })
expect(console.error).toHaveBeenCalled()
const [
message,
keyPath,
value,
actionType
] = (console.error as jest.Mock).mock.calls[0]
// error reported is from a nested class instance, rather than the `entries` function `serializableObject`
expect(message).toContain('detected in the state, in the path: `%s`')
expect(keyPath).toBe('testSlice.a.third.bad-map-instance')
expect(value).toBe(nonSerializableValue)
expect(actionType).toBe(ACTION_TYPE)
})
});
it('Should use the supplied isSerializable function to determine serializability', () => {
const ACTION_TYPE = 'TEST_ACTION'
const initialState = {
a: 0
}
const badValue = new Map()
const reducer: Reducer = (state = initialState, action) => {
switch (action.type) {
case ACTION_TYPE: {
return {
a: badValue
}
}
default:
return state
}
}
const serializableStateInvariantMiddleware = createSerializableStateInvariantMiddleware({
isSerializable: (value: any) => true
})
const store = configureStore({
reducer: {
testSlice: reducer
},
middleware: [serializableStateInvariantMiddleware]
})
store.dispatch({ type: ACTION_TYPE })
// Supplied 'isSerializable' considers all values serializable, hence
// no error logging is expected:
expect(console.error).not.toHaveBeenCalled()
})
})

@@ -43,3 +43,4 @@ import isPlainObject from './isPlainObject'

path: ReadonlyArray<string> = [],
isSerializable: (value: unknown) => boolean = isPlain
isSerializable: (value: unknown) => boolean = isPlain,
getEntries?: (value: unknown) => [string, any][]
): NonSerializableValue | false {

@@ -59,5 +60,6 @@ let foundNestedSerializable: NonSerializableValue | false

for (const property of Object.keys(value)) {
const entries = getEntries != null ? getEntries(value) : Object.entries(value);
for (const [property, nestedValue] of entries) {
const nestedPath = path.concat(property)
const nestedValue: unknown = (value as any)[property]

@@ -75,3 +77,4 @@ if (!isSerializable(nestedValue)) {

nestedPath,
isSerializable
isSerializable,
getEntries
)

@@ -97,3 +100,9 @@

*/
isSerializable?: (value: any) => boolean
isSerializable?: (value: any) => boolean,
/**
* The function that will be used to retrieve entries from each
* value. If unspecified, `Object.entries` will be used. Defaults
* to `undefined`.
*/
getEntries?: (value: any) => [string, any][],
}

@@ -111,3 +120,3 @@

): Middleware {
const { isSerializable = isPlain } = options
const { isSerializable = isPlain, getEntries } = options

@@ -118,3 +127,4 @@ return storeAPI => next => action => {

[],
isSerializable
isSerializable,
getEntries,
)

@@ -132,3 +142,8 @@

const foundStateNonSerializableValue = findNonSerializableValue(state)
const foundStateNonSerializableValue = findNonSerializableValue(
state,
[],
isSerializable,
getEntries,
)

@@ -135,0 +150,0 @@ if (foundStateNonSerializableValue) {

Sorry, the diff of this file is too big to display

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