Skip to content

Commit

Permalink
Merge branch 'release/0.7.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
charlespascoe committed Jan 10, 2018
2 parents da58ec7 + fa7bdbd commit acc5c68
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 10 deletions.
64 changes: 62 additions & 2 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export function conformsTo<T>(validator: Validator<T>, optionsOrNext?: IValidati
return errors.concat(result.addPathNode(new KeyPathNode(key)).errors);
}

partiallyValidated[key] = result.result;
partiallyValidated[key] = result.value;
return errors;
}, [] as ValidationError[]);

Expand Down Expand Up @@ -261,7 +261,7 @@ export function eachItem<T>(assertion: (arg: any) => ValidationResult<T>, next?:
);
}

const mapped = (results as SuccessResult<T>[]).map(result => result.result);
const mapped = (results as SuccessResult<T>[]).map(result => result.value);

return next ? next(mapped) : success(mapped);
};
Expand Down Expand Up @@ -289,3 +289,63 @@ export function equals<T>(value: T, ...values: T[]): (arg: any) => ValidationRes
return error('NOT_EQUAL', vals.length === 1 ? `'${arg}' does not equal '${vals[0]}'` : `'${arg}' not one of: ${vals.join(', ')}`);
};
}


export function isMap(): (arg: any) => ValidationResult<{[key: string]: any}>;
export function isMap<T>(next: (arg: {[key: string]: any}) => ValidationResult<T>): (arg: any) => ValidationResult<T>;
export function isMap(next?: (arg: any) => ValidationResult<any>): (arg: any) => ValidationResult<any> {
return isObject((arg: any) => {
const nonStringKeys = keysOf(arg).filter(key => typeof key !== 'string');

if (nonStringKeys.length > 0) {
return error('NOT_STRING_KEY', `Expected string keys, got: ${nonStringKeys.map(key => `${key} (${typeof key})`)}`);
}

return next ? next(arg) : success(arg);
});
}


export function eachValue<T>(assertion: (arg: any) => ValidationResult<T>): (arg: {[key: string]: any}) => ValidationResult<{[key: string]: T}>;
export function eachValue<T,U>(assertion: (arg: any) => ValidationResult<T>, next: (arg: {[key: string]: T}) => ValidationResult<U>): (arg: {[key: string]: any}) => ValidationResult<U>;
export function eachValue<T>(assertion: (arg: any) => ValidationResult<T>, next?: (arg: {[key: string]: T}) => ValidationResult<any>): (arg: {[key: string]: any}) => ValidationResult<any> {
return (arg: {[key: string]: any}) => {
return conformsTo(
Object.keys(arg).reduce(
(validator, key) => {
validator[key] = assertion;
return validator;
},
{} as Validator<{[key: string]: T}>
)
)(arg);
};
}


function either<A,B>(assertion1: (arg: any) => ValidationResult<A>, assertion2: (arg: any) => ValidationResult<B>): (arg: any) => ValidationResult<A | B>;
function either<A,B,C>(assertion1: (arg: any) => ValidationResult<A>, assertion2: (arg: any) => ValidationResult<B>, assertion3: (arg: any) => ValidationResult<C>): (arg: any) => ValidationResult<A | B | C>;
function either<A,B,C,D>(assertion1: (arg: any) => ValidationResult<A>, assertion2: (arg: any) => ValidationResult<B>, assertion3: (arg: any) => ValidationResult<C>, assertion4: (arg: any) => ValidationResult<D>): (arg: any) => ValidationResult<A | B | C | D>;
function either<A,B,C,D,E>(assertion1: (arg: any) => ValidationResult<A>, assertion2: (arg: any) => ValidationResult<B>, assertion3: (arg: any) => ValidationResult<C>, assertion4: (arg: any) => ValidationResult<D>, assertion5: (arg: any) => ValidationResult<E>): (arg: any) => ValidationResult<A | B | C | D | E>;
function either<A,B,C,D,E,F>(assertion1: (arg: any) => ValidationResult<A>, assertion2: (arg: any) => ValidationResult<B>, assertion3: (arg: any) => ValidationResult<C>, assertion4: (arg: any) => ValidationResult<D>, assertion5: (arg: any) => ValidationResult<E>, assertion6: (arg: any) => ValidationResult<F>): (arg: any) => ValidationResult<A | B | C | D | E | F>;
function either<A,B,C,D,E,F,G>(assertion1: (arg: any) => ValidationResult<A>, assertion2: (arg: any) => ValidationResult<B>, assertion3: (arg: any) => ValidationResult<C>, assertion4: (arg: any) => ValidationResult<D>, assertion5: (arg: any) => ValidationResult<E>, assertion6: (arg: any) => ValidationResult<F>, assertion7: (arg: any) => ValidationResult<G>): (arg: any) => ValidationResult<A | B | C | D | E | F | G>;
function either<A,B,C,D,E,F,G,H>(assertion1: (arg: any) => ValidationResult<A>, assertion2: (arg: any) => ValidationResult<B>, assertion3: (arg: any) => ValidationResult<C>, assertion4: (arg: any) => ValidationResult<D>, assertion5: (arg: any) => ValidationResult<E>, assertion6: (arg: any) => ValidationResult<F>, assertion7: (arg: any) => ValidationResult<G>, assertion8: (arg: any) => ValidationResult<H>): (arg: any) => ValidationResult<A | B | C | D | E | F | G | H>;
function either<A,B,C,D,E,F,G,H,I>(assertion1: (arg: any) => ValidationResult<A>, assertion2: (arg: any) => ValidationResult<B>, assertion3: (arg: any) => ValidationResult<C>, assertion4: (arg: any) => ValidationResult<D>, assertion5: (arg: any) => ValidationResult<E>, assertion6: (arg: any) => ValidationResult<F>, assertion7: (arg: any) => ValidationResult<G>, assertion8: (arg: any) => ValidationResult<H>, assertion9: (arg: any) => ValidationResult<I>): (arg: any) => ValidationResult<A | B | C | D | E | F | G | H | I>;
function either<A,B,C,D,E,F,G,H,I,J>(assertion1: (arg: any) => ValidationResult<A>, assertion2: (arg: any) => ValidationResult<B>, assertion3: (arg: any) => ValidationResult<C>, assertion4: (arg: any) => ValidationResult<D>, assertion5: (arg: any) => ValidationResult<E>, assertion6: (arg: any) => ValidationResult<F>, assertion7: (arg: any) => ValidationResult<G>, assertion8: (arg: any) => ValidationResult<H>, assertion9: (arg: any) => ValidationResult<I>, assertion10: (arg: any) => ValidationResult<J>): (arg: any) => ValidationResult<A | B | C | D | E | F | G | H | I | J>;
function either(...assertions: Array<(arg: any) => any>): (arg: any) => any {
return (arg: any) => {
let errors: ValidationError[] = [];

for (const assertion of assertions) {
const result = assertion(arg);

if (result.success) {
return result;
}

errors = errors.concat(result.errors);
}

return error('NO_MATCH', 'No match found - the following assertions failed:\n ' + errors.map(error => error.toString()).join('\n '));
};
}
12 changes: 6 additions & 6 deletions lib/validation-result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ export class ValidationError {
return this;
}

public toString(root: string = '$root'): string {
public toString(root: string = '$'): string {
return `${this.pathString(root)}: ${this.message}`;
}

public pathString(root: string = '$root'): string {
public pathString(root: string = '$'): string {
return root + this.path.map(node => node.toString()).join('');
}
}
Expand All @@ -74,7 +74,7 @@ export class ErrorResult {
return this;
}

public toString(root: string = '$root'): string {
public toString(root: string = '$'): string {
return `${this.errors.length} validation error${this.errors.length === 1 ? '' : 's'}:\n ${this.errors.map(error => error.toString(root)).join('\n ')}`;
}

Expand All @@ -86,7 +86,7 @@ export class ErrorResult {

export interface SuccessResult<T> {
readonly success: true;
readonly result: T;
readonly value: T;
}


Expand All @@ -100,6 +100,6 @@ export function errorFromException(err: any): ErrorResult {
}


export function success<T>(result: T): SuccessResult<T> {
return {success: true, result};
export function success<T>(value: T): SuccessResult<T> {
return {success: true, value};
}
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typed-validation",
"version": "0.6.0",
"version": "0.7.0",
"description": "Validate Objects Against TypeScript Interfaces",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down

0 comments on commit acc5c68

Please sign in to comment.