Skip to content

Commit 35612a6

Browse files
committed
Merge branch 'release/0.7.6'
2 parents 399f40f + 0f48914 commit 35612a6

File tree

6 files changed

+100
-76
lines changed

6 files changed

+100
-76
lines changed

lib/formatting.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import * as colors from 'colors/safe';
2+
import { ValidationError } from './validation-result';
3+
import { keysOf } from './utils';
4+
5+
6+
export function setColours(enabled: boolean) {
7+
(colors as any).enabled = enabled;
8+
}
9+
10+
11+
setColours(false);
12+
13+
14+
export function repeat(text: string, count: number): string {
15+
let result = '';
16+
17+
for (let i = 0; i < count; i++) {
18+
result += text;
19+
}
20+
21+
return result;
22+
}
23+
24+
25+
export function increaseIndent(text: string, indent: number): string {
26+
const indentPadding = repeat(' ', indent);
27+
return indentPadding + text.split('\n').join('\n' + indentPadding);
28+
}
29+
30+
31+
export function pluralise(count: number, singular: string, plural: string): string {
32+
return `${count} ${count === 1 ? singular : plural}`;
33+
}
34+
35+
36+
export function formatPath(root: string, path: Array<string | number>): string {
37+
return colors.magenta(root) + path
38+
.map(component => {
39+
if (typeof component === 'number') {
40+
return colors.yellow('[') + colors.red(`${component}`) + colors.yellow(']');
41+
} else if (/^[$a-z_][$a-z_0-9]*$/i.test(component)) {
42+
return colors.yellow('.') + colors.cyan(component);
43+
} else {
44+
return colors.yellow('[') + colors.red(`'${component.replace('\\', '\\\\').replace('\'', '\\\'')}'`) + colors.yellow(']')
45+
}
46+
})
47+
.join('');
48+
}
49+
50+
51+
export function formatErrorResultMessage(prefix: string, root: string, errors: ValidationError[]): string {
52+
return colors.white(colors.bgRed(colors.bold(`${prefix}${errors.length} validation error${errors.length === 1 ? '' : 's'}:`))) + '\n' +
53+
errors.map(error => increaseIndent(error.toString(root), 4)).join('\n');
54+
}
55+
56+
57+
export function formatEitherValidationErrorMessages(errorsPerType: {[description: string]: ValidationError[]}): string {
58+
return keysOf(errorsPerType)
59+
.map(desc => {
60+
const errors = errorsPerType[desc];
61+
62+
return increaseIndent(
63+
colors.bold(colors.red(`Not ${desc}, due to ${pluralise(errors.length, 'validation error', 'validation errors')}:`)) + '\n' +
64+
errors.map(error => increaseIndent(error.toString(), 4)).join('\n'),
65+
4
66+
);
67+
})
68+
.join('\n');
69+
}

lib/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import { keysOf, tryCatch, primitiveType } from './utils';
22
import {
3-
ArrayIndexPathNode,
43
error,
54
errorFromException,
65
ErrorResult,
76
SuccessResult,
8-
KeyPathNode,
97
success,
108
ValidationError,
119
ValidationResult,
1210
EitherValidationError
1311
} from './validation-result';
1412
export * from './validation-result';
13+
export { setColours } from './formatting';
14+
import { setColours } from './formatting';
1515

1616

1717
export type Validator<T> = {
@@ -79,7 +79,7 @@ export function conformsTo<T>(validator: Validator<T>, optionsOrNext?: IValidati
7979
);
8080

8181
if (!result.success) {
82-
return errors.concat(result.addPathNode(new KeyPathNode(key)).errors);
82+
return errors.concat(result.addPathSegment(key).errors);
8383
}
8484

8585
partiallyValidated[key] = result.value;
@@ -266,7 +266,7 @@ export function eachItem<T>(assertion: (arg: any) => ValidationResult<T>, next?:
266266
return new ErrorResult(
267267
results
268268
.map((item, index) => {
269-
if (!item.success) item.addPathNode(new ArrayIndexPathNode(index));
269+
if (!item.success) item.addPathSegment(index);
270270
return item;
271271
})
272272
.filter<ErrorResult>(ErrorResult.isErrorResult)

lib/utils.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,6 @@ export function keysOf<T>(arg: T): Array<keyof T> {
2020
}
2121

2222

23-
export function repeat(text: string, count: number): string {
24-
let result = '';
25-
26-
for (let i = 0; i < count; i++) {
27-
result += text;
28-
}
29-
30-
return result;
31-
}
32-
33-
34-
export function increaseIndent(text: string, indent: number): string {
35-
const indentPadding = repeat(' ', indent);
36-
return indentPadding + text.split('\n').join('\n' + indentPadding);
37-
}
38-
39-
40-
export function pluralise(count: number, singular: string, plural: string): string {
41-
return `${count} ${count === 1 ? singular : plural}`;
42-
}
4323

4424

4525
export function primitiveType(arg: any): string {

lib/validation-result.ts

Lines changed: 10 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,19 @@
1-
import { increaseIndent, keysOf, pluralise } from './utils';
1+
import { formatPath, formatErrorResultMessage, formatEitherValidationErrorMessages } from './formatting';
22

33

44
export type ValidationResult<T> = SuccessResult<T> | ErrorResult;
55

66

7-
export abstract class PathNode { }
8-
9-
10-
export class KeyPathNode extends PathNode {
11-
constructor(public readonly key: string) {
12-
super();
13-
}
14-
15-
public toString(): string {
16-
if (/^[$a-z_][$a-z0-9_]*$/i.test(this.key)) {
17-
return `.${this.key}`;
18-
} else {
19-
return `['${this.key.replace('\\', '\\\\').replace("'", "\\'")}']`;
20-
}
21-
}
22-
}
23-
24-
25-
export class ArrayIndexPathNode extends PathNode {
26-
constructor(public readonly index: number) {
27-
super();
28-
}
29-
30-
public toString(): string {
31-
return `[${this.index}]`;
32-
}
33-
}
34-
35-
367
export class ValidationError {
37-
public readonly path: PathNode[] = [];
8+
public readonly path: Array<string | number> = [];
389

3910
constructor(
4011
public readonly errorCode: string,
4112
public readonly message: string,
4213
) { }
4314

44-
public addPathNode(node: PathNode): ValidationError {
45-
this.path.unshift(node);
15+
public addPathSegment(seg: string | number): ValidationError {
16+
this.path.unshift(seg);
4617
return this;
4718
}
4819

@@ -51,7 +22,7 @@ export class ValidationError {
5122
}
5223

5324
public pathString(root: string = '$'): string {
54-
return root + this.path.map(node => node.toString()).join('');
25+
return formatPath(root, this.path);
5526
}
5627
}
5728

@@ -64,18 +35,7 @@ export class EitherValidationError extends ValidationError {
6435
}
6536

6637
public toString(root: string = '$'): string {
67-
return `${this.pathString(root)}: ${this.message} - the following assertions failed:\n` +
68-
keysOf(this.errors)
69-
.map(desc => {
70-
const errors = this.errors[desc];
71-
72-
return increaseIndent(
73-
`Not ${desc}, due to ${pluralise(errors.length, 'validation error', 'validation errors')}:\n` +
74-
errors.map(error => increaseIndent(error.toString(), 4)).join('\n'),
75-
4
76-
);
77-
})
78-
.join('\n');
38+
return `${this.pathString(root)}: ${this.message} - the following assertions failed:\n` + formatEitherValidationErrorMessages(this.errors);
7939
}
8040
}
8141

@@ -93,16 +53,16 @@ export class ErrorResult {
9353
}
9454
}
9555

96-
public addPathNode(node: PathNode): ErrorResult {
56+
public addPathSegment(seg: string | number): ErrorResult {
9757
for (const error of this.errors) {
98-
error.addPathNode(node);
58+
error.addPathSegment(seg);
9959
}
10060

10161
return this;
10262
}
10363

104-
public toString(root: string = '$'): string {
105-
return `${this.errors.length} validation error${this.errors.length === 1 ? '' : 's'}:\n${this.errors.map(error => increaseIndent(error.toString(root), 4)).join('\n')}`;
64+
public toString(root: string = '$', prefix: string = ''): string {
65+
return formatErrorResultMessage(prefix, root, this.errors);
10666
}
10767

10868
public static isErrorResult(arg: any): arg is ErrorResult {

package-lock.json

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

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "typed-validation",
3-
"version": "0.7.5",
3+
"version": "0.7.6",
44
"description": "Validate Objects Against TypeScript Interfaces",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
@@ -28,6 +28,10 @@
2828
},
2929
"homepage": "https://github.com/cpascoe95/typed-validation#readme",
3030
"devDependencies": {
31+
"@types/colors": "1.1.3",
3132
"typescript": "2.5.2"
33+
},
34+
"dependencies": {
35+
"colors": "1.1.2"
3236
}
3337
}

0 commit comments

Comments
 (0)