wip
This commit is contained in:
parent
a26de4fda5
commit
f6c4f13b57
|
@ -1,17 +1,20 @@
|
|||
import * as mongo from 'mongodb';
|
||||
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];
|
||||
|
||||
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;
|
||||
error: string;
|
||||
|
||||
|
@ -20,6 +23,9 @@ class ValidatorCore implements Validator {
|
|||
this.error = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* この値が undefined または null の場合エラーにします
|
||||
*/
|
||||
required() {
|
||||
if (this.error === null && this.value === null) {
|
||||
this.error = 'required';
|
||||
|
@ -27,11 +33,19 @@ class ValidatorCore implements Validator {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* このインスタンスの値およびエラーを取得します
|
||||
*/
|
||||
get(): [any, string] {
|
||||
return [this.value, this.error];
|
||||
}
|
||||
|
||||
validate(validator: CustomValidator<any>) {
|
||||
/**
|
||||
* このインスタンスの値に対して妥当性を検証します
|
||||
* バリデータが false または(エラーを表す)文字列を返した場合エラーにします
|
||||
* @param validator バリデータ
|
||||
*/
|
||||
validate(validator: Validator<any>) {
|
||||
if (this.error || this.value === null) return this;
|
||||
const result = validator(this.value);
|
||||
if (result === false) {
|
||||
|
@ -41,9 +55,59 @@ class ValidatorCore implements Validator {
|
|||
}
|
||||
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;
|
||||
error: string;
|
||||
|
||||
|
@ -58,6 +122,11 @@ class NumberValidator extends ValidatorCore {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 値が指定された範囲内にない場合エラーにします
|
||||
* @param min 下限
|
||||
* @param max 上限
|
||||
*/
|
||||
range(min: number, max: number) {
|
||||
if (this.error || this.value === null) return this;
|
||||
if (this.value < min || this.value > max) {
|
||||
|
@ -70,28 +139,242 @@ class NumberValidator extends ValidatorCore {
|
|||
return super.required();
|
||||
}
|
||||
|
||||
/**
|
||||
* このインスタンスの値およびエラーを取得します
|
||||
*/
|
||||
get(): [number, string] {
|
||||
return super.get();
|
||||
}
|
||||
|
||||
validate(validator: CustomValidator<number>) {
|
||||
/**
|
||||
* このインスタンスの値に対して妥当性を検証します
|
||||
* バリデータが false または(エラーを表す)文字列を返した場合エラーにします
|
||||
* @param validator バリデータ
|
||||
*/
|
||||
validate(validator: Validator<number>) {
|
||||
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) => ({
|
||||
must: {
|
||||
be: {
|
||||
a: {
|
||||
string: 0,
|
||||
number: () => new NumberValidator(value),
|
||||
boolean: 0,
|
||||
set: 0
|
||||
string: () => new StringFuctory(value),
|
||||
number: () => new NumberFuctory(value),
|
||||
boolean: () => new BooleanFuctory(value)
|
||||
},
|
||||
an: {
|
||||
id: 0,
|
||||
array: 0,
|
||||
object: 0
|
||||
id: () => new IdFuctory(value),
|
||||
array: () => new ArrayFuctory(value),
|
||||
object: () => new ObjectFuctory(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue