From e130913ab293308d731c36b3d8b21da4ac7a9e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grabowski?= Date: Thu, 7 Aug 2025 16:34:41 +0200 Subject: [PATCH 1/3] IBX-10471: [Inputs] Inputs Validators Base --- .../public/ts/validators/BaseValidator.ts | 7 +++++ .../ts/validators/IsEmptyStringValidator.ts | 11 ++++++++ .../public/ts/validators/ValidatorManager.ts | 27 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 src/bundle/Resources/public/ts/validators/BaseValidator.ts create mode 100644 src/bundle/Resources/public/ts/validators/IsEmptyStringValidator.ts create mode 100644 src/bundle/Resources/public/ts/validators/ValidatorManager.ts diff --git a/src/bundle/Resources/public/ts/validators/BaseValidator.ts b/src/bundle/Resources/public/ts/validators/BaseValidator.ts new file mode 100644 index 0000000..cb1a41a --- /dev/null +++ b/src/bundle/Resources/public/ts/validators/BaseValidator.ts @@ -0,0 +1,7 @@ +export default abstract class BaseValidator { + abstract getErrorMessage(): string; + + abstract validate(_value: unknown): boolean; +} + +export type BaseValidatorType = typeof BaseValidator; diff --git a/src/bundle/Resources/public/ts/validators/IsEmptyStringValidator.ts b/src/bundle/Resources/public/ts/validators/IsEmptyStringValidator.ts new file mode 100644 index 0000000..0bef19b --- /dev/null +++ b/src/bundle/Resources/public/ts/validators/IsEmptyStringValidator.ts @@ -0,0 +1,11 @@ +import BaseValidator from './BaseValidator'; + +export default class IsEmptyStringValidator extends BaseValidator { + getErrorMessage(): string { + return /*@Desc("This field cannot be empty.")*/ 'ibexa.validators.is_empty_string'; // TODO: Use translation service when available + } + + validate(value: string): boolean { + return value.trim() !== ''; + } +} diff --git a/src/bundle/Resources/public/ts/validators/ValidatorManager.ts b/src/bundle/Resources/public/ts/validators/ValidatorManager.ts new file mode 100644 index 0000000..b8e3db3 --- /dev/null +++ b/src/bundle/Resources/public/ts/validators/ValidatorManager.ts @@ -0,0 +1,27 @@ +import BaseValidator from './BaseValidator'; + +export default class ValidatorManager { + private _validators: BaseValidator[]; + + constructor(validators: BaseValidator[] = []) { + this._validators = validators; + } + + addValidator(validator: BaseValidator): void { + this._validators.push(validator); + } + + removeValidator(validator: BaseValidator): void { + this._validators = this._validators.filter((savedValidator) => savedValidator !== validator); + } + + validate(value: unknown) { + const errors = this._validators + .filter((validator: BaseValidator) => !validator.validate(value)) + .map((validator: BaseValidator) => validator.getErrorMessage()); + + return { isValid: !errors.length, messages: errors }; + } +} + +export type ValidatorManagerType = InstanceType; From 165ffedbff24031344d5e3f7d3aebd9b5fa89823 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grabowski?= Date: Mon, 18 Aug 2025 13:34:51 +0200 Subject: [PATCH 2/3] fixes according to copilot --- .../public/ts/validators/BaseValidator.ts | 7 +++--- .../ts/validators/IsEmptyStringValidator.ts | 2 +- .../public/ts/validators/ValidatorManager.ts | 23 +++++++++++-------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/bundle/Resources/public/ts/validators/BaseValidator.ts b/src/bundle/Resources/public/ts/validators/BaseValidator.ts index cb1a41a..2873e87 100644 --- a/src/bundle/Resources/public/ts/validators/BaseValidator.ts +++ b/src/bundle/Resources/public/ts/validators/BaseValidator.ts @@ -1,7 +1,6 @@ -export default abstract class BaseValidator { +// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters +export default abstract class BaseValidator { abstract getErrorMessage(): string; - abstract validate(_value: unknown): boolean; + abstract validate(_value: T): boolean; } - -export type BaseValidatorType = typeof BaseValidator; diff --git a/src/bundle/Resources/public/ts/validators/IsEmptyStringValidator.ts b/src/bundle/Resources/public/ts/validators/IsEmptyStringValidator.ts index 0bef19b..11c5156 100644 --- a/src/bundle/Resources/public/ts/validators/IsEmptyStringValidator.ts +++ b/src/bundle/Resources/public/ts/validators/IsEmptyStringValidator.ts @@ -1,6 +1,6 @@ import BaseValidator from './BaseValidator'; -export default class IsEmptyStringValidator extends BaseValidator { +export default class IsEmptyStringValidator extends BaseValidator { getErrorMessage(): string { return /*@Desc("This field cannot be empty.")*/ 'ibexa.validators.is_empty_string'; // TODO: Use translation service when available } diff --git a/src/bundle/Resources/public/ts/validators/ValidatorManager.ts b/src/bundle/Resources/public/ts/validators/ValidatorManager.ts index b8e3db3..af438b6 100644 --- a/src/bundle/Resources/public/ts/validators/ValidatorManager.ts +++ b/src/bundle/Resources/public/ts/validators/ValidatorManager.ts @@ -1,27 +1,30 @@ import BaseValidator from './BaseValidator'; -export default class ValidatorManager { - private _validators: BaseValidator[]; +export interface ValidateReturnType { + isValid: boolean; + messages: string[]; +} + +export default class ValidatorManager { + private _validators: BaseValidator[]; - constructor(validators: BaseValidator[] = []) { + constructor(validators: BaseValidator[] = []) { this._validators = validators; } - addValidator(validator: BaseValidator): void { + addValidator(validator: BaseValidator): void { this._validators.push(validator); } - removeValidator(validator: BaseValidator): void { + removeValidator(validator: BaseValidator): void { this._validators = this._validators.filter((savedValidator) => savedValidator !== validator); } - validate(value: unknown) { + validate(value: T): ValidateReturnType { const errors = this._validators - .filter((validator: BaseValidator) => !validator.validate(value)) - .map((validator: BaseValidator) => validator.getErrorMessage()); + .filter((validator: BaseValidator) => !validator.validate(value)) + .map((validator: BaseValidator) => validator.getErrorMessage()); return { isValid: !errors.length, messages: errors }; } } - -export type ValidatorManagerType = InstanceType; From c1aab4c5abf77bd006cc953d777621b16d9bc53a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grabowski?= Date: Fri, 22 Aug 2025 14:09:45 +0200 Subject: [PATCH 3/3] after CR --- .../public/ts/validators/BaseValidator.ts | 3 +-- .../public/ts/validators/ValidatorManager.ts | 14 +++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/bundle/Resources/public/ts/validators/BaseValidator.ts b/src/bundle/Resources/public/ts/validators/BaseValidator.ts index 2873e87..8701339 100644 --- a/src/bundle/Resources/public/ts/validators/BaseValidator.ts +++ b/src/bundle/Resources/public/ts/validators/BaseValidator.ts @@ -1,6 +1,5 @@ -// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters export default abstract class BaseValidator { abstract getErrorMessage(): string; - abstract validate(_value: T): boolean; + abstract validate(value: T): boolean; } diff --git a/src/bundle/Resources/public/ts/validators/ValidatorManager.ts b/src/bundle/Resources/public/ts/validators/ValidatorManager.ts index af438b6..757491c 100644 --- a/src/bundle/Resources/public/ts/validators/ValidatorManager.ts +++ b/src/bundle/Resources/public/ts/validators/ValidatorManager.ts @@ -1,6 +1,6 @@ import BaseValidator from './BaseValidator'; -export interface ValidateReturnType { +export interface ValidationResult { isValid: boolean; messages: string[]; } @@ -20,10 +20,14 @@ export default class ValidatorManager { this._validators = this._validators.filter((savedValidator) => savedValidator !== validator); } - validate(value: T): ValidateReturnType { - const errors = this._validators - .filter((validator: BaseValidator) => !validator.validate(value)) - .map((validator: BaseValidator) => validator.getErrorMessage()); + validate(value: T): ValidationResult { + const errors = this._validators.reduce((errorsAcc: string[], validator) => { + if (!validator.validate(value)) { + return [...errorsAcc, validator.getErrorMessage()]; + } + + return errorsAcc; + }, []); return { isValid: !errors.length, messages: errors }; }