This commit is contained in:
syuilo 2017-03-02 20:51:32 +09:00
parent a26de4fda5
commit f6c4f13b57

View File

@ -1,17 +1,20 @@
import * as mongo from 'mongodb'; import * as mongo from 'mongodb';
import hasDuplicates from '../common/has-duplicates'; import hasDuplicates from '../common/has-duplicates';
type CustomValidator<T> = (value: T) => boolean | string; type Validator<T> = (value: T) => boolean | string;
type Modifier<T> = (value: T) => T;
interface Validator { interface Fuctory {
get: () => [any, string]; get: () => [any, string];
required: () => Validator; required: () => Fuctory;
validate: (validator: CustomValidator<any>) => Validator; validate: (validator: Validator<any>) => Fuctory;
modify: (modifier: Modifier<any>) => Fuctory;
} }
class ValidatorCore implements Validator { class FuctoryCore implements Fuctory {
value: any; value: any;
error: string; error: string;
@ -20,6 +23,9 @@ class ValidatorCore implements Validator {
this.error = null; this.error = null;
} }
/**
* undefined  null
*/
required() { required() {
if (this.error === null && this.value === null) { if (this.error === null && this.value === null) {
this.error = 'required'; this.error = 'required';
@ -27,11 +33,19 @@ class ValidatorCore implements Validator {
return this; return this;
} }
/**
*
*/
get(): [any, string] { get(): [any, string] {
return [this.value, this.error]; return [this.value, this.error];
} }
validate(validator: CustomValidator<any>) { /**
*
* false ()
* @param validator
*/
validate(validator: Validator<any>) {
if (this.error || this.value === null) return this; if (this.error || this.value === null) return this;
const result = validator(this.value); const result = validator(this.value);
if (result === false) { if (result === false) {
@ -41,9 +55,59 @@ class ValidatorCore implements Validator {
} }
return this; return this;
} }
modify(modifier: Modifier<any>) {
if (this.error || this.value === null) return this;
try {
this.value = modifier(this.value);
} catch (e) {
this.error = e;
}
return this;
}
} }
class NumberValidator extends ValidatorCore { class BooleanFuctory extends FuctoryCore {
value: boolean;
error: string;
constructor(value) {
super();
if (value === undefined || value === null) {
this.value = null;
} else if (typeof value != 'boolean') {
this.error = 'must-be-a-boolean';
} else {
this.value = value;
}
}
required() {
return super.required();
}
/**
*
*/
get(): [boolean, string] {
return super.get();
}
/**
*
* false ()
* @param validator
*/
validate(validator: Validator<boolean>) {
return super.validate(validator);
}
modify(modifier: Modifier<boolean>) {
return super.modify(modifier);
}
}
class NumberFuctory extends FuctoryCore {
value: number; value: number;
error: string; error: string;
@ -58,6 +122,11 @@ class NumberValidator extends ValidatorCore {
} }
} }
/**
*
* @param min
* @param max
*/
range(min: number, max: number) { range(min: number, max: number) {
if (this.error || this.value === null) return this; if (this.error || this.value === null) return this;
if (this.value < min || this.value > max) { if (this.value < min || this.value > max) {
@ -70,28 +139,242 @@ class NumberValidator extends ValidatorCore {
return super.required(); return super.required();
} }
/**
*
*/
get(): [number, string] { get(): [number, string] {
return super.get(); return super.get();
} }
validate(validator: CustomValidator<number>) { /**
*
* false ()
* @param validator
*/
validate(validator: Validator<number>) {
return super.validate(validator); return super.validate(validator);
} }
modify(modifier: Modifier<number>) {
return super.modify(modifier);
}
}
class StringFuctory extends FuctoryCore {
value: string;
error: string;
constructor(value) {
super();
if (value === undefined || value === null) {
this.value = null;
} else if (typeof value != 'string') {
this.error = 'must-be-a-string';
} else {
this.value = value;
}
}
/**
*
* @param min
* @param max
*/
range(min: number, max: number) {
if (this.error || this.value === null) return this;
if (this.value.length < min || this.value.length > max) {
this.error = 'invalid-range';
}
return this;
}
trim() {
if (this.error || this.value === null) return this;
this.value = this.value.trim();
return this;
}
required() {
return super.required();
}
/**
*
*/
get(): [string, string] {
return super.get();
}
/**
*
* false ()
* @param validator
*/
validate(validator: Validator<string>) {
return super.validate(validator);
}
modify(modifier: Modifier<string>) {
return super.modify(modifier);
}
}
class ArrayFuctory extends FuctoryCore {
value: any[];
error: string;
constructor(value) {
super();
if (value === undefined || value === null) {
this.value = null;
} else if (!Array.isArray(value)) {
this.error = 'must-be-an-array';
} else {
this.value = value;
}
}
/**
* (=)
*/
unique() {
if (this.error || this.value === null) return this;
if (hasDuplicates(this.value)) {
this.error = 'must-be-unique';
}
return this;
}
/**
*
* @param min
* @param max
*/
range(min: number, max: number) {
if (this.error || this.value === null) return this;
if (this.value.length < min || this.value.length > max) {
this.error = 'invalid-range';
}
return this;
}
required() {
return super.required();
}
/**
*
*/
get(): [any[], string] {
return super.get();
}
/**
*
* false ()
* @param validator
*/
validate(validator: Validator<any[]>) {
return super.validate(validator);
}
modify(modifier: Modifier<any[]>) {
return super.modify(modifier);
}
}
class IdFuctory extends FuctoryCore {
value: mongo.ObjectID;
error: string;
constructor(value) {
super();
if (value === undefined || value === null) {
this.value = null;
} else if (typeof value != 'string' || !mongo.ObjectID.isValid(value)) {
this.error = 'must-be-an-id';
} else {
this.value = new mongo.ObjectID(value);
}
}
required() {
return super.required();
}
/**
*
*/
get(): [any[], string] {
return super.get();
}
/**
*
* false ()
* @param validator
*/
validate(validator: Validator<any[]>) {
return super.validate(validator);
}
modify(modifier: Modifier<any[]>) {
return super.modify(modifier);
}
}
class ObjectFuctory extends FuctoryCore {
value: any;
error: string;
constructor(value) {
super();
if (value === undefined || value === null) {
this.value = null;
} else if (typeof value != 'object') {
this.error = 'must-be-an-object';
} else {
this.value = value;
}
}
required() {
return super.required();
}
/**
*
*/
get(): [any, string] {
return super.get();
}
/**
*
* false ()
* @param validator
*/
validate(validator: Validator<any>) {
return super.validate(validator);
}
modify(modifier: Modifier<any>) {
return super.modify(modifier);
}
} }
const it = (value: any) => ({ const it = (value: any) => ({
must: { must: {
be: { be: {
a: { a: {
string: 0, string: () => new StringFuctory(value),
number: () => new NumberValidator(value), number: () => new NumberFuctory(value),
boolean: 0, boolean: () => new BooleanFuctory(value)
set: 0
}, },
an: { an: {
id: 0, id: () => new IdFuctory(value),
array: 0, array: () => new ArrayFuctory(value),
object: 0 object: () => new ObjectFuctory(value)
} }
} }
} }