Skip to content

Commit

Permalink
feat(validators): add custom error messages property (#150)
Browse files Browse the repository at this point in the history
  • Loading branch information
KirillDyachkovskiy authored Dec 14, 2023
1 parent 77c1a47 commit 0130131
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 36 deletions.
6 changes: 4 additions & 2 deletions src/lib/kit/validators/messages.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import i18n from '../i18n';
import {subscribeConfigure} from '../i18n/configure';

const getErrorMessages = () => ({
import type {ErrorMessagesType} from './types';

const getErrorMessages = (): ErrorMessagesType => ({
REQUIRED: i18n('label_error-required'),
INVALID: i18n('label_error-invalid'),
INT: i18n('label_error-int'),
Expand Down Expand Up @@ -30,7 +32,7 @@ const getErrorMessages = () => ({
ZERO_START: i18n('label_error-zero-start'),
});

export let ErrorMessages = getErrorMessages();
export let ErrorMessages: ErrorMessagesType = getErrorMessages();

subscribeConfigure(() => {
ErrorMessages = getErrorMessages();
Expand Down
16 changes: 16 additions & 0 deletions src/lib/kit/validators/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export interface ErrorMessagesType {
REQUIRED: string;
INVALID: string;
INT: string;
NUMBER: string;
minLength: (count: number | bigint) => string;
minLengthArr: (count: number | bigint) => string;
maxLength: (count: number | bigint) => string;
maxLengthArr: (count: number | bigint) => string;
minNumber: (count: number | bigint) => string;
maxNumber: (count: number | bigint) => string;
SPACE_START: string;
SPACE_END: string;
DOT_END: string;
ZERO_START: string;
}
77 changes: 43 additions & 34 deletions src/lib/kit/validators/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,61 +12,66 @@ import {
import {ErrorMessages} from '../validators';

import {isFloat, isInt} from './helpers';
import {ErrorMessagesType} from './types';

export interface GetArrayValidatorParams {
interface CommonValidatorParams {
ignoreRequiredCheck?: boolean;
customErrorMessages?: Partial<ErrorMessagesType>;
}

export interface GetArrayValidatorParams extends CommonValidatorParams {
ignoreMaxLengthCheck?: boolean;
ignoreMinLengthCheck?: boolean;
}

export const getArrayValidator = (params: GetArrayValidatorParams = {}) => {
const {ignoreRequiredCheck, ignoreMaxLengthCheck, ignoreMinLengthCheck} = params;
const {ignoreRequiredCheck, ignoreMaxLengthCheck, ignoreMinLengthCheck, customErrorMessages} =
params;
const errorMessages = {...ErrorMessages, ...customErrorMessages};

return (spec: ArraySpec, value?: ArrayValue) => {
const valueLength = value?.length || 0;

if (!ignoreRequiredCheck && spec.required && !_.isArray(value)) {
return ErrorMessages.REQUIRED;
return errorMessages.REQUIRED;
}

if (
!ignoreMaxLengthCheck &&
typeof spec.maxLength === 'bigint' &&
valueLength > spec.maxLength
) {
return ErrorMessages.maxLengthArr(spec.maxLength);
return errorMessages.maxLengthArr(spec.maxLength);
}

if (
!ignoreMinLengthCheck &&
typeof spec.minLength === 'bigint' &&
valueLength < spec.minLength
) {
return ErrorMessages.minLengthArr(spec.minLength);
return errorMessages.minLengthArr(spec.minLength);
}

return false;
};
};

export interface GetBooleanValidatorParams {
ignoreRequiredCheck?: boolean;
}
export interface GetBooleanValidatorParams extends CommonValidatorParams {}

export const getBooleanValidator = (params: GetBooleanValidatorParams = {}) => {
const {ignoreRequiredCheck} = params;
const {ignoreRequiredCheck, customErrorMessages} = params;
const errorMessages = {...ErrorMessages, ...customErrorMessages};

return (spec: BooleanSpec, value?: boolean) => {
if (!ignoreRequiredCheck && spec.required && !value) {
return ErrorMessages.REQUIRED;
return errorMessages.REQUIRED;
}

return false;
};
};

export interface GetNumberValidatorParams {
ignoreRequiredCheck?: boolean;
export interface GetNumberValidatorParams extends CommonValidatorParams {
ignoreSpaceStartCheck?: boolean;
ignoreSpaceEndCheck?: boolean;
ignoreNumberCheck?: boolean;
Expand All @@ -88,30 +93,33 @@ export const getNumberValidator = (params: GetNumberValidatorParams = {}) => {
ignoreIntCheck,
ignoreDotEnd,
ignoreZeroStart,
customErrorMessages,
} = params;
const errorMessages = {...ErrorMessages, ...customErrorMessages};

// eslint-disable-next-line complexity
return (spec: NumberSpec, value: string | number = '') => {
const stringValue = String(value);

if (!ignoreRequiredCheck && spec.required && !stringValue.length) {
return ErrorMessages.REQUIRED;
return errorMessages.REQUIRED;
}

if (stringValue.length) {
if (!ignoreSpaceStartCheck && !stringValue[0].trim()) {
return ErrorMessages.SPACE_START;
return errorMessages.SPACE_START;
}

if (!ignoreSpaceEndCheck && !stringValue[stringValue.length - 1].trim()) {
return ErrorMessages.SPACE_END;
return errorMessages.SPACE_END;
}

if (!ignoreDotEnd && stringValue[stringValue.length - 1] === '.') {
return ErrorMessages.DOT_END;
return errorMessages.DOT_END;
}

if (!ignoreNumberCheck && !isFloat(stringValue)) {
return ErrorMessages.NUMBER;
return errorMessages.NUMBER;
}

if (
Expand All @@ -121,7 +129,7 @@ export const getNumberValidator = (params: GetNumberValidatorParams = {}) => {
stringValue.substring(0, 2) === '-0' &&
stringValue[2] !== '.'))
) {
return ErrorMessages.ZERO_START;
return errorMessages.ZERO_START;
}
}

Expand All @@ -131,7 +139,7 @@ export const getNumberValidator = (params: GetNumberValidatorParams = {}) => {
stringValue.length &&
Number(stringValue) > spec.maximum
) {
return ErrorMessages.maxNumber(spec.maximum);
return errorMessages.maxNumber(spec.maximum);
}

if (
Expand All @@ -140,37 +148,35 @@ export const getNumberValidator = (params: GetNumberValidatorParams = {}) => {
stringValue.length &&
spec.minimum > Number(stringValue)
) {
return ErrorMessages.minNumber(spec.minimum);
return errorMessages.minNumber(spec.minimum);
}

if (_.isString(spec.format) && stringValue.length) {
if (!ignoreIntCheck && spec.format === 'int64' && !isInt(stringValue)) {
return ErrorMessages.INT;
return errorMessages.INT;
}
}

return false;
};
};

export interface GetObjectValidatorParams {
ignoreRequiredCheck?: boolean;
}
export interface GetObjectValidatorParams extends CommonValidatorParams {}

export const getObjectValidator = (params: GetObjectValidatorParams = {}) => {
const {ignoreRequiredCheck} = params;
const {ignoreRequiredCheck, customErrorMessages} = params;
const errorMessages = {...ErrorMessages, ...customErrorMessages};

return (spec: ObjectSpec, value?: ObjectValue) => {
if (!ignoreRequiredCheck && spec.required && !value) {
return ErrorMessages.REQUIRED;
return errorMessages.REQUIRED;
}

return false;
};
};

export interface GetStringValidatorParams {
ignoreRequiredCheck?: boolean;
export interface GetStringValidatorParams extends CommonValidatorParams {
ignoreSpaceStartCheck?: boolean;
ignoreSpaceEndCheck?: boolean;
ignoreMaxLengthCheck?: boolean;
Expand All @@ -186,22 +192,25 @@ export const getStringValidator = (params: GetStringValidatorParams = {}) => {
ignoreMaxLengthCheck,
ignoreMinLengthCheck,
ignoreRegExpCheck,
customErrorMessages,
} = params;
const errorMessages = {...ErrorMessages, ...customErrorMessages};

// eslint-disable-next-line complexity
return (spec: StringSpec, value = '') => {
const valueLength = value?.length;

if (!ignoreRequiredCheck && spec.required && !valueLength) {
return ErrorMessages.REQUIRED;
return errorMessages.REQUIRED;
}

if (valueLength) {
if (!ignoreSpaceStartCheck && !value[0].trim()) {
return ErrorMessages.SPACE_START;
return errorMessages.SPACE_START;
}

if (!ignoreSpaceEndCheck && !value[value.length - 1].trim()) {
return ErrorMessages.SPACE_END;
return errorMessages.SPACE_END;
}
}

Expand All @@ -210,15 +219,15 @@ export const getStringValidator = (params: GetStringValidatorParams = {}) => {
typeof spec.maxLength === 'bigint' &&
valueLength > spec.maxLength
) {
return ErrorMessages.maxLength(spec.maxLength);
return errorMessages.maxLength(spec.maxLength);
}

if (
!ignoreMinLengthCheck &&
typeof spec.minLength === 'bigint' &&
valueLength < spec.minLength
) {
return ErrorMessages.minLength(spec.minLength);
return errorMessages.minLength(spec.minLength);
}

if (_.isString(spec.pattern) && spec.pattern.length) {
Expand All @@ -227,7 +236,7 @@ export const getStringValidator = (params: GetStringValidatorParams = {}) => {
if (!ignoreRegExpCheck && !regex.test(value)) {
return _.isString(spec.patternError) && spec.patternError.length
? spec.patternError
: ErrorMessages.INVALID;
: errorMessages.INVALID;
}
}

Expand Down

0 comments on commit 0130131

Please sign in to comment.