Skip to content

Commit acc5c68

Browse files
committed
Merge branch 'release/0.7.0'
2 parents da58ec7 + fa7bdbd commit acc5c68

File tree

4 files changed

+70
-10
lines changed

4 files changed

+70
-10
lines changed

lib/index.ts

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export function conformsTo<T>(validator: Validator<T>, optionsOrNext?: IValidati
8383
return errors.concat(result.addPathNode(new KeyPathNode(key)).errors);
8484
}
8585

86-
partiallyValidated[key] = result.result;
86+
partiallyValidated[key] = result.value;
8787
return errors;
8888
}, [] as ValidationError[]);
8989

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

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

266266
return next ? next(mapped) : success(mapped);
267267
};
@@ -289,3 +289,63 @@ export function equals<T>(value: T, ...values: T[]): (arg: any) => ValidationRes
289289
return error('NOT_EQUAL', vals.length === 1 ? `'${arg}' does not equal '${vals[0]}'` : `'${arg}' not one of: ${vals.join(', ')}`);
290290
};
291291
}
292+
293+
294+
export function isMap(): (arg: any) => ValidationResult<{[key: string]: any}>;
295+
export function isMap<T>(next: (arg: {[key: string]: any}) => ValidationResult<T>): (arg: any) => ValidationResult<T>;
296+
export function isMap(next?: (arg: any) => ValidationResult<any>): (arg: any) => ValidationResult<any> {
297+
return isObject((arg: any) => {
298+
const nonStringKeys = keysOf(arg).filter(key => typeof key !== 'string');
299+
300+
if (nonStringKeys.length > 0) {
301+
return error('NOT_STRING_KEY', `Expected string keys, got: ${nonStringKeys.map(key => `${key} (${typeof key})`)}`);
302+
}
303+
304+
return next ? next(arg) : success(arg);
305+
});
306+
}
307+
308+
309+
export function eachValue<T>(assertion: (arg: any) => ValidationResult<T>): (arg: {[key: string]: any}) => ValidationResult<{[key: string]: T}>;
310+
export function eachValue<T,U>(assertion: (arg: any) => ValidationResult<T>, next: (arg: {[key: string]: T}) => ValidationResult<U>): (arg: {[key: string]: any}) => ValidationResult<U>;
311+
export function eachValue<T>(assertion: (arg: any) => ValidationResult<T>, next?: (arg: {[key: string]: T}) => ValidationResult<any>): (arg: {[key: string]: any}) => ValidationResult<any> {
312+
return (arg: {[key: string]: any}) => {
313+
return conformsTo(
314+
Object.keys(arg).reduce(
315+
(validator, key) => {
316+
validator[key] = assertion;
317+
return validator;
318+
},
319+
{} as Validator<{[key: string]: T}>
320+
)
321+
)(arg);
322+
};
323+
}
324+
325+
326+
function either<A,B>(assertion1: (arg: any) => ValidationResult<A>, assertion2: (arg: any) => ValidationResult<B>): (arg: any) => ValidationResult<A | B>;
327+
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>;
328+
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>;
329+
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>;
330+
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>;
331+
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>;
332+
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>;
333+
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>;
334+
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>;
335+
function either(...assertions: Array<(arg: any) => any>): (arg: any) => any {
336+
return (arg: any) => {
337+
let errors: ValidationError[] = [];
338+
339+
for (const assertion of assertions) {
340+
const result = assertion(arg);
341+
342+
if (result.success) {
343+
return result;
344+
}
345+
346+
errors = errors.concat(result.errors);
347+
}
348+
349+
return error('NO_MATCH', 'No match found - the following assertions failed:\n ' + errors.map(error => error.toString()).join('\n '));
350+
};
351+
}

lib/validation-result.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ export class ValidationError {
4343
return this;
4444
}
4545

46-
public toString(root: string = '$root'): string {
46+
public toString(root: string = '$'): string {
4747
return `${this.pathString(root)}: ${this.message}`;
4848
}
4949

50-
public pathString(root: string = '$root'): string {
50+
public pathString(root: string = '$'): string {
5151
return root + this.path.map(node => node.toString()).join('');
5252
}
5353
}
@@ -74,7 +74,7 @@ export class ErrorResult {
7474
return this;
7575
}
7676

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

@@ -86,7 +86,7 @@ export class ErrorResult {
8686

8787
export interface SuccessResult<T> {
8888
readonly success: true;
89-
readonly result: T;
89+
readonly value: T;
9090
}
9191

9292

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

102102

103-
export function success<T>(result: T): SuccessResult<T> {
104-
return {success: true, result};
103+
export function success<T>(value: T): SuccessResult<T> {
104+
return {success: true, value};
105105
}

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "typed-validation",
3-
"version": "0.6.0",
3+
"version": "0.7.0",
44
"description": "Validate Objects Against TypeScript Interfaces",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

0 commit comments

Comments
 (0)