diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2017-03-02 20:51:32 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2017-03-02 20:51:32 +0900 |
| commit | f6c4f13b5773da3316a483f8bd5d7ae0c7f993db (patch) | |
| tree | 1517188943ef1791206d3b27d6aa5ebc26a0c79f /src | |
| parent | いい感じに (diff) | |
| download | sharkey-f6c4f13b5773da3316a483f8bd5d7ae0c7f993db.tar.gz sharkey-f6c4f13b5773da3316a483f8bd5d7ae0c7f993db.tar.bz2 sharkey-f6c4f13b5773da3316a483f8bd5d7ae0c7f993db.zip | |
wip
Diffstat (limited to 'src')
| -rw-r--r-- | src/api/validator2.ts | 313 |
1 files changed, 298 insertions, 15 deletions
diff --git a/src/api/validator2.ts b/src/api/validator2.ts index ed58f445d3..04dff59aac 100644 --- a/src/api/validator2.ts +++ b/src/api/validator2.ts @@ -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 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 NumberValidator extends ValidatorCore { +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) } } } |