From e92dbe9558df6fa93a78b6060be3f22fa5000185 Mon Sep 17 00:00:00 2001 From: Jayden Date: Sat, 12 Nov 2022 20:33:18 +0900 Subject: [PATCH] fix(sanitizer) (#661) * Add test for #660 * Implement sanitizeValue * Mark sanitizeValue private --- deno_dist/validator/validator.ts | 17 +++++++------- src/validator/validator.test.ts | 40 ++++++++++++++++++++++++++++++++ src/validator/validator.ts | 17 +++++++------- 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/deno_dist/validator/validator.ts b/deno_dist/validator/validator.ts index 476a903e..c901e4d4 100644 --- a/deno_dist/validator/validator.ts +++ b/deno_dist/validator/validator.ts @@ -242,6 +242,8 @@ export abstract class VBase { if (this._nested()) jsonData = dst } + value = this.sanitizeValue(value) + const results: ValidateResult[] = [] let typeRule = this.rules.shift() @@ -271,6 +273,13 @@ export abstract class VBase { return this.isArray ? `${prefix} "${this.type}[]"` : `${prefix} "${this.type}"` } + private sanitizeValue = (value: Type) => ( + this.sanitizers.reduce( + (acc, sanitizer) => sanitizer(acc), + value + ) + ) + private validateRule(rule: Rule, value: Type): ValidateResult { let isValid: boolean = false @@ -332,10 +341,6 @@ export abstract class VBase { if (Array.isArray(value)) { if (value.length === 0 && !this._optional) return false - // Sanitize - for (const sanitizer of this.sanitizers) { - value = value.map((innerVal: any) => sanitizer(innerVal)) as JSONArray - } for (const val of value) { if (!func(val)) { return false @@ -343,10 +348,6 @@ export abstract class VBase { } return true } else { - // Sanitize - for (const sanitizer of this.sanitizers) { - value = sanitizer(value) - } if (!func(value)) { return false } diff --git a/src/validator/validator.test.ts b/src/validator/validator.test.ts index 5318e8cb..b19e2081 100644 --- a/src/validator/validator.test.ts +++ b/src/validator/validator.test.ts @@ -815,3 +815,43 @@ describe('Custom rule', () => { ) }) }) + +describe('Sanitizer', () => { + describe('built-in', () => { + test('trim', async () => { + const v = new Validator() + + const post = { name: ' a bc ' } + + const req = new Request('http://localhost/', { + method: 'POST', + body: JSON.stringify(post), + }) + + const validator = v.json('name').trim() + const [result] = await validator.validate(req) + + expect(result.value).toBe('a bc') + }) + }) + + test('custom', async () => { + const v = new Validator() + + const post = { name: ' a bc ' } + + const req = new Request('http://localhost/', { + method: 'POST', + body: JSON.stringify(post), + }) + + const validator = v + .json('name') + .addSanitizer((s: unknown) => `${s}`.replace(/\s/g, '')) + .addSanitizer((s: unknown) => `${s}`.toUpperCase()) + + const [results] = await validator.validate(req) + + expect(results.value).toBe('ABC') + }) +}) diff --git a/src/validator/validator.ts b/src/validator/validator.ts index 603a627d..b82313f9 100644 --- a/src/validator/validator.ts +++ b/src/validator/validator.ts @@ -242,6 +242,8 @@ export abstract class VBase { if (this._nested()) jsonData = dst } + value = this.sanitizeValue(value) + const results: ValidateResult[] = [] let typeRule = this.rules.shift() @@ -271,6 +273,13 @@ export abstract class VBase { return this.isArray ? `${prefix} "${this.type}[]"` : `${prefix} "${this.type}"` } + private sanitizeValue = (value: Type) => ( + this.sanitizers.reduce( + (acc, sanitizer) => sanitizer(acc), + value + ) + ) + private validateRule(rule: Rule, value: Type): ValidateResult { let isValid: boolean = false @@ -332,10 +341,6 @@ export abstract class VBase { if (Array.isArray(value)) { if (value.length === 0 && !this._optional) return false - // Sanitize - for (const sanitizer of this.sanitizers) { - value = value.map((innerVal: any) => sanitizer(innerVal)) as JSONArray - } for (const val of value) { if (!func(val)) { return false @@ -343,10 +348,6 @@ export abstract class VBase { } return true } else { - // Sanitize - for (const sanitizer of this.sanitizers) { - value = sanitizer(value) - } if (!func(value)) { return false }