summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2017-03-02 20:51:32 +0900
committersyuilo <syuilotan@yahoo.co.jp>2017-03-02 20:51:32 +0900
commitf6c4f13b5773da3316a483f8bd5d7ae0c7f993db (patch)
tree1517188943ef1791206d3b27d6aa5ebc26a0c79f /src
parentいい感じに (diff)
downloadsharkey-f6c4f13b5773da3316a483f8bd5d7ae0c7f993db.tar.gz
sharkey-f6c4f13b5773da3316a483f8bd5d7ae0c7f993db.tar.bz2
sharkey-f6c4f13b5773da3316a483f8bd5d7ae0c7f993db.zip
wip
Diffstat (limited to 'src')
-rw-r--r--src/api/validator2.ts313
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)
}
}
}