Skip to content
This repository has been archived by the owner on Aug 3, 2022. It is now read-only.

Commit

Permalink
recentry release branch (#24)
Browse files Browse the repository at this point in the history
* temp

* new library setting

* feat(all): new feature key setting more flexible by idselector

BREAKING CHANGE: errorId is not set default if idSelector provided

* add test case

* fix(fix state hierarchy wrong bug):

* chore(release): 5.0.0
  • Loading branch information
tkow authored Feb 2, 2019
1 parent bf89a2b commit 7b14781
Show file tree
Hide file tree
Showing 10 changed files with 216 additions and 849 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

<a name="5.0.0"></a>
# [5.0.0](https://github.com/tkow/redux-state-validation/compare/v4.3.0...v5.0.0) (2019-02-02)


### Features

* **all:** new feature key setting more flexible by idselector ([57c77fd](https://github.com/tkow/redux-state-validation/commit/57c77fd))


### BREAKING CHANGES

* **all:** errorId is not set default if idSelector provided



<a name="4.3.0"></a>
# [4.3.0](https://github.com/tkow/redux-state-validation/compare/v4.2.0...v4.3.0) (2019-02-01)

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"email": "t.kusama06130220@gmail.com",
"url": "https://twitter.com/tkow39"
},
"version": "4.3.0",
"version": "5.0.0",
"description": "add validator to reducer result handy",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
Expand Down Expand Up @@ -78,7 +78,7 @@
"tslint-config-prettier": "^1.15.0",
"tslint-immutable": "^4.7.0",
"typedoc": "^0.13.0",
"typescript": "^3.0.3"
"typescript": "^3.3.1"
},
"ava": {
"failFast": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,40 @@ export abstract class AbstractValidationWatcher<
error: Error,
{ validator, action }: WithErrorOptions<T, Action>
): ResultValue;
public mapIdToObject = <Key extends string, Value extends ResultValue>(
ids: Key[],
prevStateArray: Value[],
updateValue: Value
): Value => {
let result: Value | { [key: string]: Value } = updateValue;
while (ids.length > 0) {
const hierarchicalObject = prevStateArray.pop();
const _key: string = ids.pop();
result = {
[_key]: {
...hierarchicalObject,
...result
}
};
}
return {
...prevStateArray.pop(),
...result
} as Value;
};

public getCompositeObjectArray(keys: string[], obj: object) {
let current = { ...obj };
return keys.reduce(
(value, nextKey) => {
current = current && current[nextKey];
if (current) {
return [...value, current];
} else {
return [...value, {}];
}
},
[current]
);
}
}
24 changes: 16 additions & 8 deletions src/lib/ArrayValidationWatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
AbstractValidationWatcher,
InternalParams,
WithErrorOptions
} from "./AbstractValidationWather";
} from "./AbstractValidationWatcher";
import { ArrayResultValue, Error } from "./types";

export class ArrayValidationWatcher extends AbstractValidationWatcher<"array"> {
Expand Down Expand Up @@ -38,16 +38,24 @@ export class ArrayValidationWatcher extends AbstractValidationWatcher<"array"> {
error: Error,
{ validator, action }: WithErrorOptions<T, Action>
): ArrayResultValue => {
const _results = { ...results };
const key = validator.idSelector
const _result = { ...results };
let keys = validator.idSelector
? validator.idSelector(error.id, action)
: error.id;
if (!_results[key]) {
_results[key] = [];
if (typeof keys === "string") {
keys = [keys];
}
return {
..._results,
[key]: [...(_results[key] as Error[]), error]
const prevStateArray = this.getCompositeObjectArray([...keys], _result);
const primaryId = keys.pop();
let nextError: ArrayResultValue = {
[primaryId]: [error]
};
if (Array.isArray(prevStateArray[prevStateArray.length - 1])) {
const tempArray = prevStateArray.pop() as Error[];
nextError = {
[primaryId]: [...tempArray, error]
};
}
return this.mapIdToObject(keys, prevStateArray, nextError);
};
}
32 changes: 10 additions & 22 deletions src/lib/ObjectValidationWatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ import {
AbstractValidationWatcher,
InternalParams,
WithErrorOptions
} from "./AbstractValidationWather";
} from "./AbstractValidationWatcher";
import { Error, ObjectResultValue } from "./types";

export class ObjectValidationWatcher extends AbstractValidationWatcher<
"object"
> {
protected internal: InternalParams<{
[id: string]: Error | { [id: string]: Error };
}>;
protected internal: InternalParams<ObjectResultValue>;

constructor(internal = {}) {
super();
Expand Down Expand Up @@ -42,24 +40,14 @@ export class ObjectValidationWatcher extends AbstractValidationWatcher<
error: Error,
{ validator, action }: WithErrorOptions<T, Action>
): ObjectResultValue => {
let _result = { ...results };
if (validator.idSelector) {
const key = validator.idSelector(error.id, action);
if (!_result[key]) {
_result[key] = {};
}
return {
...(_result as { [id: string]: { [id: string]: Error } }),
[key]: {
..._result[key],
[error.id]: error
}
};
} else {
return (_result = {
...(_result as ObjectResultValue),
[error.id]: error
});
const _result = { ...results };
let keys = validator.idSelector
? validator.idSelector(error.id, action)
: error.id;
if (typeof keys === "string") {
keys = [keys];
}
const prevStateArray = this.getCompositeObjectArray(keys, _result);
return this.mapIdToObject(keys, prevStateArray, error);
};
}
6 changes: 3 additions & 3 deletions src/lib/ValidationWatcherFactory.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AbstractValidationWatcher } from "./AbstractValidationWather";
import { AbstractValidationWatcher } from "./AbstractValidationWatcher";
import { ArrayValidationWatcher } from "./ArrayValidationWatcher";
import { ObjectValidationWatcher } from "./ObjectValidationWatcher";
import {
Expand Down Expand Up @@ -94,8 +94,8 @@ export class ValidationWatcherFactory {
const stateValidationResults = Object.keys(validators).reduce(
(current, key, _index) => {
const result = validators[key].reduce((_result, _validator) => {
const invalid = !_validator.validate(value[key], {}) && value[key] !== undefined;
console.log(value[key])
const invalid =
!_validator.validate(value[key], {}) && value[key] !== undefined;
if (invalid) {
return this._validationWatcher.getErrorResults(
_result,
Expand Down
33 changes: 14 additions & 19 deletions src/lib/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ test("createStaticValidator correct works with Error", async t => {
}
];
const validate = createStaticValidator({ state: validatorsLocal });
store.dispatch(validate({state:{ postalCode: "hoge" }}));
store.dispatch(validate({ state: { postalCode: "hoge" } }));
const result = store.getState().errors;
t.deepEqual(result, errors);
});
Expand All @@ -147,9 +147,8 @@ test("createStaticValidator correct works with no Error", async t => {
}
];
const validate = createStaticValidator({ state: validatorsLocal });
store.dispatch(validate({state:{ postalCode: 123 }}));
store.dispatch(validate({ state: { postalCode: 123 } }));
const result = store.getState().errors;
console.log(result)
t.deepEqual(result, errors);
t.deepEqual(result, {});
});
Expand Down Expand Up @@ -405,7 +404,7 @@ test("use idSelector restructure errors id", async t => {
message: "Invalid PostalCode"
},
idSelector: (errorId, action: { meta?: { id: string } }) =>
(action.meta && action.meta.id) || errorId,
(action.meta && action.meta.id) + "/" + errorId,
validate: (_, action: any) => Number(action.value) > 100
},
{
Expand All @@ -414,7 +413,7 @@ test("use idSelector restructure errors id", async t => {
message: "Invalid PostalCode"
},
idSelector: (errorId, action: { meta?: { id: string } }) =>
(action.meta && action.meta.id) || errorId,
(action.meta && action.meta.id) + "/" + errorId,
validate: _ => false
}
])
Expand All @@ -430,23 +429,20 @@ test("use idSelector restructure errors id", async t => {
});
const state = store.getState();
t.truthy(
(state.errors.addidSelector as any).postalCode1.id === "postalCode1"
(state.errors as any)["addidSelector/postalCode1"].id === "postalCode1"
);
t.truthy(
(state.errors.addidSelector as any).postalCode2.id === "postalCode2"
(state.errors as any)["addidSelector/postalCode2"].id === "postalCode2"
);
t.truthy(Object.keys(state.errors).length === 1);
t.truthy(Object.keys(state.errors.addidSelector).length === 2);
t.truthy(Object.keys(state.errors).length === 2);
t.deepEqual(state.errors, {
addidSelector: {
postalCode1: {
id: "postalCode1",
message: "Invalid PostalCode"
},
postalCode2: {
id: "postalCode2",
message: "Invalid PostalCode"
}
"addidSelector/postalCode1": {
id: "postalCode1",
message: "Invalid PostalCode"
},
"addidSelector/postalCode2": {
id: "postalCode2",
message: "Invalid PostalCode"
}
});
});
Expand Down Expand Up @@ -550,7 +546,6 @@ test("can rename errorStateId for array", async t => {

test("can set action for errors", async t => {
const action = setValidatorResults({ foo: { id: "bar", message: "error" } });
console.log(action);
t.deepEqual(action, {
payload: { foo: { id: "bar", message: "error" } },
type: "@@REDUX_STATE_VALIDATION/SET_VALIDATIONS"
Expand Down
11 changes: 8 additions & 3 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,20 @@ export interface Validator<T, Action = ReduxAction> {
error: Error;
afterReduce?: boolean;
strict?: boolean;
idSelector?(id?: string, action?: Action): string;
idSelector?(id?: string, action?: Action): string | string[];
validate(state: T, action?: Action): boolean;
}

export type RecursiveArrayType = Error[] | { [id: string]: RecursiveArrayType };

export interface ArrayResultValue {
[id: string]: Error[];
[id: string]: RecursiveArrayType;
}

export type RecursiveObjectType = Error | { [id: string]: RecursiveObjectType };

export interface ObjectResultValue {
[id: string]: Error | { [id: string]: Error };
[id: string]: RecursiveObjectType;
}

export type ResultValue = ArrayResultValue | ObjectResultValue;
Loading

0 comments on commit 7b14781

Please # to comment.