@astral/validations 4.14.6 → 4.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +153 -0
- package/core/utils/index.d.ts +5 -4
- package/core/utils/index.js +5 -4
- package/core/utils/isDateEarlier/index.d.ts +1 -0
- package/core/utils/isDateEarlier/index.js +1 -0
- package/core/utils/isDateEarlier/isDateEarlier.d.ts +1 -0
- package/core/utils/isDateEarlier/isDateEarlier.js +4 -0
- package/index.d.ts +4 -0
- package/index.js +4 -0
- package/package.json +3 -2
- package/rangeDate/constants.d.ts +7 -0
- package/rangeDate/constants.js +25 -0
- package/rangeDate/index.d.ts +2 -0
- package/rangeDate/index.js +2 -0
- package/rangeDate/rangeDate.d.ts +48 -0
- package/rangeDate/rangeDate.js +60 -0
- package/rangeDateInterval/constants.d.ts +7 -0
- package/rangeDateInterval/constants.js +14 -0
- package/rangeDateInterval/index.d.ts +2 -0
- package/rangeDateInterval/index.js +2 -0
- package/rangeDateInterval/rangeDateInterval.d.ts +23 -0
- package/rangeDateInterval/rangeDateInterval.js +36 -0
- package/rangeDateInterval/types.d.ts +6 -0
- package/rangeDateInterval/types.js +1 -0
- package/rangeDateMinMax/constants.d.ts +8 -0
- package/rangeDateMinMax/constants.js +13 -0
- package/rangeDateMinMax/index.d.ts +2 -0
- package/rangeDateMinMax/index.js +2 -0
- package/rangeDateMinMax/rangeDateMinMax.d.ts +34 -0
- package/rangeDateMinMax/rangeDateMinMax.js +74 -0
- package/rangeDateMinMax/types.d.ts +2 -0
- package/rangeDateMinMax/types.js +1 -0
- package/rangeDateNotEqual/constants.d.ts +2 -0
- package/rangeDateNotEqual/constants.js +5 -0
- package/rangeDateNotEqual/index.d.ts +2 -0
- package/rangeDateNotEqual/index.js +2 -0
- package/rangeDateNotEqual/rangeDateNotEqual.d.ts +20 -0
- package/rangeDateNotEqual/rangeDateNotEqual.js +29 -0
package/README.md
CHANGED
@@ -52,6 +52,10 @@
|
|
52
52
|
- [min](#min-date)
|
53
53
|
- [max](#max-date)
|
54
54
|
- [minYearsOld](#min-years-old-date)
|
55
|
+
- [rangeDate](#range-date)
|
56
|
+
- [rangeDateInterval](#range-date-interval)
|
57
|
+
- [rangeDateMinMax](#range-date-minmax)
|
58
|
+
- [rangeDateNotEqual](#range-date-notequal)
|
55
59
|
- [boolean](#boolean)
|
56
60
|
- [object](#object)
|
57
61
|
- [partial](#partial)
|
@@ -989,6 +993,155 @@ validate(new Date('10.10.2005'));
|
|
989
993
|
|
990
994
|
---
|
991
995
|
|
996
|
+
### rangeDate
|
997
|
+
|
998
|
+
Проверяет даты интервала на обязательность заполнения, валидность значений и хронологический порядок
|
999
|
+
|
1000
|
+
```ts
|
1001
|
+
import { rangeDate } from '@astral/validations';
|
1002
|
+
|
1003
|
+
const validate = rangeDate();
|
1004
|
+
|
1005
|
+
// { message: 'Укажите период' }
|
1006
|
+
validate({});
|
1007
|
+
|
1008
|
+
// { message: 'Укажите дату окончания' }
|
1009
|
+
validate({
|
1010
|
+
start: new Date('2024.09.05'),
|
1011
|
+
})
|
1012
|
+
|
1013
|
+
// { message: 'Укажите дату начала' }
|
1014
|
+
validate({
|
1015
|
+
end: new Date('2024.09.24'),
|
1016
|
+
})
|
1017
|
+
|
1018
|
+
// { message: 'Дата начала некорректная' }
|
1019
|
+
validate({
|
1020
|
+
start: new Date('2024.99.99'),
|
1021
|
+
end: new Date('2024.09.24'),
|
1022
|
+
})
|
1023
|
+
|
1024
|
+
// { message: 'Дата окончания некорректная' }
|
1025
|
+
validate({
|
1026
|
+
start: new Date('2024.09.05'),
|
1027
|
+
end: new Date('2024.99.99'),
|
1028
|
+
})
|
1029
|
+
|
1030
|
+
// { message: 'Дата окончания не может быть раньше даты начала' }
|
1031
|
+
validate({
|
1032
|
+
start: new Date('2024.09.24'),
|
1033
|
+
end: new Date('2024.09.05'),
|
1034
|
+
})
|
1035
|
+
|
1036
|
+
// undefined
|
1037
|
+
validate({
|
1038
|
+
start: new Date('2024.09.05'),
|
1039
|
+
end: new Date('2024.09.24'),
|
1040
|
+
});
|
1041
|
+
|
1042
|
+
```
|
1043
|
+
|
1044
|
+
---
|
1045
|
+
|
1046
|
+
#### rangeDateInterval
|
1047
|
+
|
1048
|
+
Позволяет ограничить интервал на конкретное значение.
|
1049
|
+
По умолчанию значение интервала задаётся в днях, но с помощью опции unit можно задать значение в месяцах или годах.
|
1050
|
+
|
1051
|
+
```ts
|
1052
|
+
import { rangeDateInterval } from '@astral/validations';
|
1053
|
+
|
1054
|
+
const validate = object(rangeDateInterval({ limit: 14 }));
|
1055
|
+
|
1056
|
+
// { message: 'Период не может превышать 14 дней' }
|
1057
|
+
validate({
|
1058
|
+
start: new Date('2024.09.05'),
|
1059
|
+
end: new Date('2024.09.24'),
|
1060
|
+
});
|
1061
|
+
|
1062
|
+
// undefined
|
1063
|
+
validate({
|
1064
|
+
start: new Date('2024.09.05'),
|
1065
|
+
end: new Date('2024.09.12'),
|
1066
|
+
});
|
1067
|
+
|
1068
|
+
const validateMonthInterval = object(rangeDateInterval({ limit: 2, unit: 'month' }));
|
1069
|
+
|
1070
|
+
// { message: 'Период не может превышать 2 месяца' }
|
1071
|
+
validateMonthInterval({
|
1072
|
+
start: new Date('2024.09.05'),
|
1073
|
+
end: new Date('2024.12.24'),
|
1074
|
+
});
|
1075
|
+
|
1076
|
+
// undefined
|
1077
|
+
validateMonthInterval({
|
1078
|
+
start: new Date('2024.09.05'),
|
1079
|
+
end: new Date('2024.09.12'),
|
1080
|
+
});
|
1081
|
+
|
1082
|
+
|
1083
|
+
```
|
1084
|
+
|
1085
|
+
---
|
1086
|
+
|
1087
|
+
#### rangeDateMinMax
|
1088
|
+
|
1089
|
+
Проверяет даты на минимальное и максимальное допустимое значение
|
1090
|
+
|
1091
|
+
```ts
|
1092
|
+
import { rangeDateMinMax } from '@astral/validations';
|
1093
|
+
|
1094
|
+
const validate = object(rangeDateMinMax({ start: { min: { limit: new Date('2024.09.05') }}, end: { max: { limit: new Date('2024.09.15') } } }))
|
1095
|
+
|
1096
|
+
// { message: 'Дата начала должна быть позже 05.09.2024' }
|
1097
|
+
validate({
|
1098
|
+
start: new Date('2024.09.01'),
|
1099
|
+
end: new Date('2024.09.10'),
|
1100
|
+
});
|
1101
|
+
|
1102
|
+
// { message: 'Дата окончания должна быть раньше 15.09.2024}' }
|
1103
|
+
validate({
|
1104
|
+
start: new Date('2024.09.06'),
|
1105
|
+
end: new Date('2024.09.20'),
|
1106
|
+
});
|
1107
|
+
|
1108
|
+
// undefined
|
1109
|
+
validate({
|
1110
|
+
start: new Date('2024.09.06'),
|
1111
|
+
end: new Date('2024.09.14'),
|
1112
|
+
});
|
1113
|
+
|
1114
|
+
```
|
1115
|
+
|
1116
|
+
---
|
1117
|
+
|
1118
|
+
#### rangeDateNotEqual
|
1119
|
+
|
1120
|
+
Проверяет даты интервала на совпадение даты начала и окончания
|
1121
|
+
|
1122
|
+
```ts
|
1123
|
+
import { rangeDateNotEqual } from '@astral/validations';
|
1124
|
+
|
1125
|
+
const validate = object(
|
1126
|
+
rangeDateNotEqual(),
|
1127
|
+
);
|
1128
|
+
|
1129
|
+
// { message: 'Даты начала и окончания не могут совпадать' }
|
1130
|
+
validate({
|
1131
|
+
start: new Date('2024.09.05'),
|
1132
|
+
end: new Date('2024.09.05'),
|
1133
|
+
});
|
1134
|
+
|
1135
|
+
// undefined
|
1136
|
+
validate({
|
1137
|
+
start: new Date('2024.09.05'),
|
1138
|
+
end: new Date('2024.09.06'),
|
1139
|
+
});
|
1140
|
+
|
1141
|
+
```
|
1142
|
+
|
1143
|
+
---
|
1144
|
+
|
992
1145
|
## boolean
|
993
1146
|
|
994
1147
|
- Возвращает ошибку если:
|
package/core/utils/index.d.ts
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
export * from './
|
1
|
+
export * from './isDateEarlier';
|
2
|
+
export * from './isFullNameValidCharacters';
|
3
|
+
export * from './isHasConsecutiveChars';
|
2
4
|
export * from './isNoDoubleZeroStart';
|
3
|
-
export * from './resetTime';
|
4
5
|
export * from './isStartsWithAndEndsWithLetter';
|
5
|
-
export * from './
|
6
|
-
export * from './isFullNameValidCharacters';
|
6
|
+
export * from './isStringOfZeros';
|
7
7
|
export * from './isValidFullNameLength';
|
8
|
+
export * from './resetTime';
|
package/core/utils/index.js
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
export * from './
|
1
|
+
export * from './isDateEarlier';
|
2
|
+
export * from './isFullNameValidCharacters';
|
3
|
+
export * from './isHasConsecutiveChars';
|
2
4
|
export * from './isNoDoubleZeroStart';
|
3
|
-
export * from './resetTime';
|
4
5
|
export * from './isStartsWithAndEndsWithLetter';
|
5
|
-
export * from './
|
6
|
-
export * from './isFullNameValidCharacters';
|
6
|
+
export * from './isStringOfZeros';
|
7
7
|
export * from './isValidFullNameLength';
|
8
|
+
export * from './resetTime';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './isDateEarlier';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './isDateEarlier';
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const isDateEarlier: (dateA: Date, dateB: Date) => boolean;
|
package/index.d.ts
CHANGED
@@ -45,3 +45,7 @@ export { when } from './when';
|
|
45
45
|
export { toPrettyError } from './toPrettyError';
|
46
46
|
export { transform } from './transform';
|
47
47
|
export { enabled } from './enabled';
|
48
|
+
export { rangeDate, RANGE_DATE_END_EARLIER_START_ERROR_INFO, RANGE_DATE_END_INVALID_ERROR_INFO, RANGE_DATE_END_REQUIRED_ERROR_INFO, RANGE_DATE_REQUIRED_ERROR_INFO, RANGE_DATE_START_INVALID_ERROR_INFO, RANGE_DATE_START_REQUIRED_ERROR_INFO, } from './rangeDate';
|
49
|
+
export { rangeDateInterval, RANGE_DATE_INTERVAL_ERROR_INFO, } from './rangeDateInterval';
|
50
|
+
export { rangeDateMinMax, RANGE_DATE_MAX_ERROR_INFO, RANGE_DATE_MIN_ERROR_INFO, } from './rangeDateMinMax';
|
51
|
+
export { rangeDateNotEqual, RANGE_DATE_NOT_EQUAL_ERROR_INFO, } from './rangeDateNotEqual';
|
package/index.js
CHANGED
@@ -45,3 +45,7 @@ export { when } from './when';
|
|
45
45
|
export { toPrettyError } from './toPrettyError';
|
46
46
|
export { transform } from './transform';
|
47
47
|
export { enabled } from './enabled';
|
48
|
+
export { rangeDate, RANGE_DATE_END_EARLIER_START_ERROR_INFO, RANGE_DATE_END_INVALID_ERROR_INFO, RANGE_DATE_END_REQUIRED_ERROR_INFO, RANGE_DATE_REQUIRED_ERROR_INFO, RANGE_DATE_START_INVALID_ERROR_INFO, RANGE_DATE_START_REQUIRED_ERROR_INFO, } from './rangeDate';
|
49
|
+
export { rangeDateInterval, RANGE_DATE_INTERVAL_ERROR_INFO, } from './rangeDateInterval';
|
50
|
+
export { rangeDateMinMax, RANGE_DATE_MAX_ERROR_INFO, RANGE_DATE_MIN_ERROR_INFO, } from './rangeDateMinMax';
|
51
|
+
export { rangeDateNotEqual, RANGE_DATE_NOT_EQUAL_ERROR_INFO, } from './rangeDateNotEqual';
|
package/package.json
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "@astral/validations",
|
3
|
-
"version": "4.
|
3
|
+
"version": "4.15.0",
|
4
4
|
"browser": "./index.js",
|
5
5
|
"main": "./index.js",
|
6
6
|
"dependencies": {
|
7
7
|
"is-plain-obj": "^4.1.0",
|
8
|
-
"utility-types": "^3.10.0"
|
8
|
+
"utility-types": "^3.10.0",
|
9
|
+
"@astral/utils": "^1.1.0"
|
9
10
|
},
|
10
11
|
"author": "Astral.Soft",
|
11
12
|
"license": "MIT",
|
@@ -0,0 +1,7 @@
|
|
1
|
+
import { type ErrorInfo } from '../core';
|
2
|
+
export declare const RANGE_DATE_REQUIRED_ERROR_INFO: ErrorInfo;
|
3
|
+
export declare const RANGE_DATE_START_REQUIRED_ERROR_INFO: ErrorInfo;
|
4
|
+
export declare const RANGE_DATE_END_REQUIRED_ERROR_INFO: ErrorInfo;
|
5
|
+
export declare const RANGE_DATE_START_INVALID_ERROR_INFO: ErrorInfo;
|
6
|
+
export declare const RANGE_DATE_END_INVALID_ERROR_INFO: ErrorInfo;
|
7
|
+
export declare const RANGE_DATE_END_EARLIER_START_ERROR_INFO: ErrorInfo;
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import { createErrorCode } from '../core';
|
2
|
+
export const RANGE_DATE_REQUIRED_ERROR_INFO = {
|
3
|
+
code: createErrorCode('rangedate-required'),
|
4
|
+
message: 'Укажите период',
|
5
|
+
};
|
6
|
+
export const RANGE_DATE_START_REQUIRED_ERROR_INFO = {
|
7
|
+
code: createErrorCode('rangedate-startRequired'),
|
8
|
+
message: 'Укажите дату начала',
|
9
|
+
};
|
10
|
+
export const RANGE_DATE_END_REQUIRED_ERROR_INFO = {
|
11
|
+
code: createErrorCode('rangedate-endRequired'),
|
12
|
+
message: 'Укажите дату окончания',
|
13
|
+
};
|
14
|
+
export const RANGE_DATE_START_INVALID_ERROR_INFO = {
|
15
|
+
code: createErrorCode('rangedate-startInvalid'),
|
16
|
+
message: 'Дата начала некорректная',
|
17
|
+
};
|
18
|
+
export const RANGE_DATE_END_INVALID_ERROR_INFO = {
|
19
|
+
code: createErrorCode('rangedate-endInvalid'),
|
20
|
+
message: 'Дата окончания некорректная',
|
21
|
+
};
|
22
|
+
export const RANGE_DATE_END_EARLIER_START_ERROR_INFO = {
|
23
|
+
code: createErrorCode('rangedate-endEarlierStart'),
|
24
|
+
message: 'Дата окончания не может быть раньше даты начала',
|
25
|
+
};
|
@@ -0,0 +1,48 @@
|
|
1
|
+
type RangeDateValue = {
|
2
|
+
start?: Date;
|
3
|
+
end?: Date;
|
4
|
+
};
|
5
|
+
type RangeDateParams = {
|
6
|
+
/**
|
7
|
+
* Позволяет пометить дату как необязательная
|
8
|
+
*/
|
9
|
+
required?: {
|
10
|
+
/**
|
11
|
+
* Если `false` дата начала будет не обязательна
|
12
|
+
* @default true
|
13
|
+
*/
|
14
|
+
start?: boolean;
|
15
|
+
/**
|
16
|
+
* Если `false` дата окончания будет не обязательна
|
17
|
+
* @default true
|
18
|
+
*/
|
19
|
+
end?: boolean;
|
20
|
+
};
|
21
|
+
/**
|
22
|
+
* Позволяет переопределить дефолтные сообщения об ошибках
|
23
|
+
*/
|
24
|
+
messages?: {
|
25
|
+
/**
|
26
|
+
* Для даты начала
|
27
|
+
*/
|
28
|
+
startRequired?: string;
|
29
|
+
/**
|
30
|
+
* Для даты окончания
|
31
|
+
*/
|
32
|
+
endRequired?: string;
|
33
|
+
/**
|
34
|
+
* Если дата окончания раньше даты начала
|
35
|
+
*/
|
36
|
+
endEarlierStart?: string;
|
37
|
+
};
|
38
|
+
};
|
39
|
+
/**
|
40
|
+
* Проверяет даты интервала на обязательность заполнения, валидность значений и хронологический порядок
|
41
|
+
* @example
|
42
|
+
* ```ts
|
43
|
+
* const validate = object(rangeDate());
|
44
|
+
* validate({ start: new Date(), end: new Date() });
|
45
|
+
* ```
|
46
|
+
*/
|
47
|
+
export declare const rangeDate: <TLastSchemaValues extends Record<string, unknown>>(params?: RangeDateParams) => (value: RangeDateValue, prevCtx?: import("../core").ValidationContext<TLastSchemaValues> | undefined) => import("../core").ValidationResult;
|
48
|
+
export {};
|
@@ -0,0 +1,60 @@
|
|
1
|
+
import { isDate } from '@astral/utils';
|
2
|
+
import { createRule, isDateEarlier } from '../core';
|
3
|
+
import { RANGE_DATE_END_EARLIER_START_ERROR_INFO, RANGE_DATE_END_INVALID_ERROR_INFO, RANGE_DATE_END_REQUIRED_ERROR_INFO, RANGE_DATE_REQUIRED_ERROR_INFO, RANGE_DATE_START_INVALID_ERROR_INFO, RANGE_DATE_START_REQUIRED_ERROR_INFO, } from './constants';
|
4
|
+
/**
|
5
|
+
* Проверяет даты интервала на обязательность заполнения, валидность значений и хронологический порядок
|
6
|
+
* @example
|
7
|
+
* ```ts
|
8
|
+
* const validate = object(rangeDate());
|
9
|
+
* validate({ start: new Date(), end: new Date() });
|
10
|
+
* ```
|
11
|
+
*/
|
12
|
+
export const rangeDate = (params) => createRule((value, ctx) => {
|
13
|
+
const { required, messages } = Object.assign(Object.assign({}, (params || {})), { required: {
|
14
|
+
start: (params === null || params === void 0 ? void 0 : params.required) && 'start' in (params === null || params === void 0 ? void 0 : params.required)
|
15
|
+
? params === null || params === void 0 ? void 0 : params.required.start
|
16
|
+
: true,
|
17
|
+
end: (params === null || params === void 0 ? void 0 : params.required) && 'end' in (params === null || params === void 0 ? void 0 : params.required)
|
18
|
+
? params === null || params === void 0 ? void 0 : params.required.end
|
19
|
+
: true,
|
20
|
+
} });
|
21
|
+
if ((required === null || required === void 0 ? void 0 : required.start) && (required === null || required === void 0 ? void 0 : required.end) && !value.start && !value.end) {
|
22
|
+
return ctx.createError({
|
23
|
+
message: RANGE_DATE_REQUIRED_ERROR_INFO.message,
|
24
|
+
code: RANGE_DATE_REQUIRED_ERROR_INFO.code,
|
25
|
+
});
|
26
|
+
}
|
27
|
+
if ((required === null || required === void 0 ? void 0 : required.start) && !value.start) {
|
28
|
+
return ctx.createError({
|
29
|
+
message: (messages === null || messages === void 0 ? void 0 : messages.startRequired) ||
|
30
|
+
RANGE_DATE_START_REQUIRED_ERROR_INFO.message,
|
31
|
+
code: RANGE_DATE_START_REQUIRED_ERROR_INFO.code,
|
32
|
+
});
|
33
|
+
}
|
34
|
+
if ((required === null || required === void 0 ? void 0 : required.end) && !value.end) {
|
35
|
+
return ctx.createError({
|
36
|
+
message: (messages === null || messages === void 0 ? void 0 : messages.endRequired) || RANGE_DATE_END_REQUIRED_ERROR_INFO.message,
|
37
|
+
code: RANGE_DATE_END_REQUIRED_ERROR_INFO.code,
|
38
|
+
});
|
39
|
+
}
|
40
|
+
if ((value === null || value === void 0 ? void 0 : value.start) && !isDate(value.start)) {
|
41
|
+
return ctx.createError({
|
42
|
+
message: RANGE_DATE_START_INVALID_ERROR_INFO.message,
|
43
|
+
code: RANGE_DATE_START_INVALID_ERROR_INFO.code,
|
44
|
+
});
|
45
|
+
}
|
46
|
+
if ((value === null || value === void 0 ? void 0 : value.end) && !isDate(value.end)) {
|
47
|
+
return ctx.createError({
|
48
|
+
message: RANGE_DATE_END_INVALID_ERROR_INFO.message,
|
49
|
+
code: RANGE_DATE_END_INVALID_ERROR_INFO.code,
|
50
|
+
});
|
51
|
+
}
|
52
|
+
if (value.end && value.start && isDateEarlier(value.end, value.start)) {
|
53
|
+
return ctx.createError({
|
54
|
+
message: (messages === null || messages === void 0 ? void 0 : messages.endEarlierStart) ||
|
55
|
+
RANGE_DATE_END_EARLIER_START_ERROR_INFO.message,
|
56
|
+
code: RANGE_DATE_END_EARLIER_START_ERROR_INFO.code,
|
57
|
+
});
|
58
|
+
}
|
59
|
+
return undefined;
|
60
|
+
});
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { declensionDay, declensionMonth, declensionYear } from '@astral/utils';
|
2
|
+
import { createErrorCode } from '../core';
|
3
|
+
const selectDeclensionUnitStrategy = (unit) => {
|
4
|
+
const strategy = {
|
5
|
+
day: declensionDay,
|
6
|
+
month: declensionMonth,
|
7
|
+
year: declensionYear,
|
8
|
+
};
|
9
|
+
return strategy[unit];
|
10
|
+
};
|
11
|
+
export const RANGE_DATE_INTERVAL_ERROR_INFO = {
|
12
|
+
code: createErrorCode('rangedate-interval'),
|
13
|
+
message: (limit, unit) => `Период не может превышать ${limit} ${selectDeclensionUnitStrategy(unit)(limit)}`,
|
14
|
+
};
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import type { DateUnit, RangeDateValue } from './types';
|
2
|
+
type RangeDateIntervalParams = {
|
3
|
+
limit: number;
|
4
|
+
/**
|
5
|
+
* Еденицы измерения лимита
|
6
|
+
* @default 'day'
|
7
|
+
*/
|
8
|
+
unit?: DateUnit;
|
9
|
+
/**
|
10
|
+
* Замена стандартного сообщения об ошибки
|
11
|
+
*/
|
12
|
+
message?: string;
|
13
|
+
};
|
14
|
+
/**
|
15
|
+
* Позволяет ограничить интервал на конкретное значение. Установка интревала возможна в следующих единицах: день, месяц и год.
|
16
|
+
* @example
|
17
|
+
* ```ts
|
18
|
+
* const validate = object(rangeDateInterval({ limit: 14 }));
|
19
|
+
* validate({ start: new Date('2024.08.15'), end: new Date('2024.09.05') });
|
20
|
+
* ```
|
21
|
+
*/
|
22
|
+
export declare const rangeDateInterval: <TLastSchemaValues extends Record<string, unknown>>(params: RangeDateIntervalParams) => (value: RangeDateValue, prevCtx?: import("../core").ValidationContext<TLastSchemaValues> | undefined) => import("../core").ValidationResult;
|
23
|
+
export {};
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { addDays, addMonths, addYears, isDate } from '@astral/utils';
|
2
|
+
import { createRule, isDateEarlier } from '../core';
|
3
|
+
import { RANGE_DATE_INTERVAL_ERROR_INFO } from './constants';
|
4
|
+
const selectAddingStrategy = (unit) => {
|
5
|
+
const strategy = {
|
6
|
+
day: addDays,
|
7
|
+
month: addMonths,
|
8
|
+
year: addYears,
|
9
|
+
};
|
10
|
+
return strategy[unit];
|
11
|
+
};
|
12
|
+
/**
|
13
|
+
* Позволяет ограничить интервал на конкретное значение. Установка интревала возможна в следующих единицах: день, месяц и год.
|
14
|
+
* @example
|
15
|
+
* ```ts
|
16
|
+
* const validate = object(rangeDateInterval({ limit: 14 }));
|
17
|
+
* validate({ start: new Date('2024.08.15'), end: new Date('2024.09.05') });
|
18
|
+
* ```
|
19
|
+
*/
|
20
|
+
export const rangeDateInterval = (params) => createRule((value, ctx) => {
|
21
|
+
const { limit, unit = 'day', message } = params;
|
22
|
+
if (!value.start || !value.end) {
|
23
|
+
return undefined;
|
24
|
+
}
|
25
|
+
if (!isDate(value.start) || !isDate(value.end)) {
|
26
|
+
return undefined;
|
27
|
+
}
|
28
|
+
const addLimits = selectAddingStrategy(unit);
|
29
|
+
if (!isDateEarlier(value.end, addLimits(value.start, limit))) {
|
30
|
+
return ctx.createError({
|
31
|
+
message: message || RANGE_DATE_INTERVAL_ERROR_INFO.message(limit, unit),
|
32
|
+
code: RANGE_DATE_INTERVAL_ERROR_INFO.code,
|
33
|
+
});
|
34
|
+
}
|
35
|
+
return undefined;
|
36
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { type ErrorInfo } from '../core';
|
2
|
+
import type { DefaultMessage } from './types';
|
3
|
+
type DynamicErrorInfo = Pick<ErrorInfo, 'code'> & {
|
4
|
+
message: DefaultMessage;
|
5
|
+
};
|
6
|
+
export declare const RANGE_DATE_MIN_ERROR_INFO: DynamicErrorInfo;
|
7
|
+
export declare const RANGE_DATE_MAX_ERROR_INFO: DynamicErrorInfo;
|
8
|
+
export {};
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { createErrorCode } from '../core';
|
2
|
+
const DEFAULT_FIELD_NAME = {
|
3
|
+
start: 'начала',
|
4
|
+
end: 'окончания',
|
5
|
+
};
|
6
|
+
export const RANGE_DATE_MIN_ERROR_INFO = {
|
7
|
+
code: createErrorCode('rangedate-min'),
|
8
|
+
message: (field, minDate) => `Дата ${DEFAULT_FIELD_NAME[field]} должна быть позже ${minDate}`,
|
9
|
+
};
|
10
|
+
export const RANGE_DATE_MAX_ERROR_INFO = {
|
11
|
+
code: createErrorCode('rangedate-max'),
|
12
|
+
message: (field, maxDate) => `Дата ${DEFAULT_FIELD_NAME[field]} должна быть раньше ${maxDate}`,
|
13
|
+
};
|
@@ -0,0 +1,34 @@
|
|
1
|
+
type RangeDateValue = {
|
2
|
+
start?: Date;
|
3
|
+
end?: Date;
|
4
|
+
};
|
5
|
+
type LimitOptions = {
|
6
|
+
/**
|
7
|
+
* Дата
|
8
|
+
*/
|
9
|
+
limit: Date;
|
10
|
+
/**
|
11
|
+
* Замена стандартного сообщения ошибки
|
12
|
+
*/
|
13
|
+
message?: (field: 'start' | 'end', date: string) => string;
|
14
|
+
};
|
15
|
+
type RangeDateMinMaxParams = {
|
16
|
+
start?: {
|
17
|
+
min?: LimitOptions;
|
18
|
+
max?: LimitOptions;
|
19
|
+
};
|
20
|
+
end?: {
|
21
|
+
min?: LimitOptions;
|
22
|
+
max?: LimitOptions;
|
23
|
+
};
|
24
|
+
};
|
25
|
+
/**
|
26
|
+
* Проверяет даты на минимальное и максимальное допустимое значение
|
27
|
+
* @example
|
28
|
+
* ```ts
|
29
|
+
* const validate = object(rangeDateMinMax({ start: { min: { limit: new Date(2023, 0, 1) }}, end: { max: { limit: new Date() } } }));
|
30
|
+
* validate({ start: new Date(), end: new Date() });
|
31
|
+
* ```
|
32
|
+
*/
|
33
|
+
export declare const rangeDateMinMax: <TLastSchemaValues extends Record<string, unknown>>(params?: RangeDateMinMaxParams) => (value: RangeDateValue, prevCtx?: import("../core").ValidationContext<TLastSchemaValues> | undefined) => import("../core").ValidationResult;
|
34
|
+
export {};
|
@@ -0,0 +1,74 @@
|
|
1
|
+
import { isDate } from '@astral/utils';
|
2
|
+
import { createRule, isDateEarlier } from '../core';
|
3
|
+
import { RANGE_DATE_END_INVALID_ERROR_INFO, RANGE_DATE_START_INVALID_ERROR_INFO, } from '../rangeDate';
|
4
|
+
import { RANGE_DATE_MAX_ERROR_INFO, RANGE_DATE_MIN_ERROR_INFO, } from './constants';
|
5
|
+
const formatDateToView = (date) => {
|
6
|
+
return new Intl.DateTimeFormat('ru-RU').format(date);
|
7
|
+
};
|
8
|
+
/**
|
9
|
+
* Проверяет даты на минимальное и максимальное допустимое значение
|
10
|
+
* @example
|
11
|
+
* ```ts
|
12
|
+
* const validate = object(rangeDateMinMax({ start: { min: { limit: new Date(2023, 0, 1) }}, end: { max: { limit: new Date() } } }));
|
13
|
+
* validate({ start: new Date(), end: new Date() });
|
14
|
+
* ```
|
15
|
+
*/
|
16
|
+
export const rangeDateMinMax = (params) => createRule((value, ctx) => {
|
17
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
18
|
+
if (!value.start && !value.end) {
|
19
|
+
return undefined;
|
20
|
+
}
|
21
|
+
if ((value === null || value === void 0 ? void 0 : value.start) && !isDate(value.start)) {
|
22
|
+
return ctx.createError({
|
23
|
+
message: RANGE_DATE_START_INVALID_ERROR_INFO.message,
|
24
|
+
code: RANGE_DATE_START_INVALID_ERROR_INFO.code,
|
25
|
+
});
|
26
|
+
}
|
27
|
+
if ((value === null || value === void 0 ? void 0 : value.end) && !isDate(value.end)) {
|
28
|
+
return ctx.createError({
|
29
|
+
message: RANGE_DATE_END_INVALID_ERROR_INFO.message,
|
30
|
+
code: RANGE_DATE_END_INVALID_ERROR_INFO.code,
|
31
|
+
});
|
32
|
+
}
|
33
|
+
// Если дата начала раньше заданной минимальной
|
34
|
+
if (((_b = (_a = params === null || params === void 0 ? void 0 : params.start) === null || _a === void 0 ? void 0 : _a.min) === null || _b === void 0 ? void 0 : _b.limit) &&
|
35
|
+
value.start &&
|
36
|
+
isDateEarlier(value.start, (_c = params === null || params === void 0 ? void 0 : params.start.min) === null || _c === void 0 ? void 0 : _c.limit)) {
|
37
|
+
return ctx.createError({
|
38
|
+
message: ((_e = (_d = params.start.min).message) === null || _e === void 0 ? void 0 : _e.call(_d, 'start', formatDateToView(params.start.min.limit))) ||
|
39
|
+
RANGE_DATE_MIN_ERROR_INFO.message('start', formatDateToView(params.start.min.limit)),
|
40
|
+
code: RANGE_DATE_MIN_ERROR_INFO.code,
|
41
|
+
});
|
42
|
+
}
|
43
|
+
// Если дата начала позже заданной максимальной
|
44
|
+
if (((_g = (_f = params === null || params === void 0 ? void 0 : params.start) === null || _f === void 0 ? void 0 : _f.max) === null || _g === void 0 ? void 0 : _g.limit) &&
|
45
|
+
value.start &&
|
46
|
+
isDateEarlier((_h = params === null || params === void 0 ? void 0 : params.start.max) === null || _h === void 0 ? void 0 : _h.limit, value.start)) {
|
47
|
+
return ctx.createError({
|
48
|
+
message: ((_k = (_j = params.start.max).message) === null || _k === void 0 ? void 0 : _k.call(_j, 'start', formatDateToView(params.start.max.limit))) ||
|
49
|
+
RANGE_DATE_MAX_ERROR_INFO.message('start', formatDateToView(params.start.max.limit)),
|
50
|
+
code: RANGE_DATE_MAX_ERROR_INFO.code,
|
51
|
+
});
|
52
|
+
}
|
53
|
+
// Если дата окончания раньше заданной минимальной
|
54
|
+
if (((_m = (_l = params === null || params === void 0 ? void 0 : params.end) === null || _l === void 0 ? void 0 : _l.min) === null || _m === void 0 ? void 0 : _m.limit) &&
|
55
|
+
value.end &&
|
56
|
+
isDateEarlier(value.end, (_o = params === null || params === void 0 ? void 0 : params.end.min) === null || _o === void 0 ? void 0 : _o.limit)) {
|
57
|
+
return ctx.createError({
|
58
|
+
message: ((_q = (_p = params.end.min).message) === null || _q === void 0 ? void 0 : _q.call(_p, 'start', formatDateToView(params.end.min.limit))) ||
|
59
|
+
RANGE_DATE_MIN_ERROR_INFO.message('end', formatDateToView(params.end.min.limit)),
|
60
|
+
code: RANGE_DATE_MIN_ERROR_INFO.code,
|
61
|
+
});
|
62
|
+
}
|
63
|
+
// Если дата окончания позже заданной максимально
|
64
|
+
if (((_s = (_r = params === null || params === void 0 ? void 0 : params.end) === null || _r === void 0 ? void 0 : _r.max) === null || _s === void 0 ? void 0 : _s.limit) &&
|
65
|
+
value.end &&
|
66
|
+
isDateEarlier((_t = params === null || params === void 0 ? void 0 : params.end.max) === null || _t === void 0 ? void 0 : _t.limit, value.end)) {
|
67
|
+
return ctx.createError({
|
68
|
+
message: ((_v = (_u = params.end.max).message) === null || _v === void 0 ? void 0 : _v.call(_u, 'start', formatDateToView(params.end.max.limit))) ||
|
69
|
+
RANGE_DATE_MAX_ERROR_INFO.message('end', formatDateToView(params.end.max.limit)),
|
70
|
+
code: RANGE_DATE_MAX_ERROR_INFO.code,
|
71
|
+
});
|
72
|
+
}
|
73
|
+
return undefined;
|
74
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,20 @@
|
|
1
|
+
type RangeDateValue = {
|
2
|
+
start?: Date;
|
3
|
+
end?: Date;
|
4
|
+
};
|
5
|
+
type RangeDateNotEqualParams = {
|
6
|
+
/**
|
7
|
+
* Замена стандартного сообщения ошибки
|
8
|
+
*/
|
9
|
+
message?: string;
|
10
|
+
};
|
11
|
+
/**
|
12
|
+
* Проверяет даты интервала на совпадение даты начала и окончания
|
13
|
+
* @example
|
14
|
+
* ```ts
|
15
|
+
* const validate = object(rangeDateNotEqual());
|
16
|
+
* validate({ start: new Date(), end: new Date() });
|
17
|
+
* ```
|
18
|
+
*/
|
19
|
+
export declare const rangeDateNotEqual: <TLastSchemaValues extends Record<string, unknown>>(params?: RangeDateNotEqualParams) => (value: RangeDateValue, prevCtx?: import("../core").ValidationContext<TLastSchemaValues> | undefined) => import("../core").ValidationResult;
|
20
|
+
export {};
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { isDate } from '@astral/utils';
|
2
|
+
import { createRule, resetTime } from '../core';
|
3
|
+
import { RANGE_DATE_NOT_EQUAL_ERROR_INFO } from './constants';
|
4
|
+
const isDateEqual = (dateA, dateB) => {
|
5
|
+
return resetTime(dateA).getTime() === resetTime(dateB).getTime();
|
6
|
+
};
|
7
|
+
/**
|
8
|
+
* Проверяет даты интервала на совпадение даты начала и окончания
|
9
|
+
* @example
|
10
|
+
* ```ts
|
11
|
+
* const validate = object(rangeDateNotEqual());
|
12
|
+
* validate({ start: new Date(), end: new Date() });
|
13
|
+
* ```
|
14
|
+
*/
|
15
|
+
export const rangeDateNotEqual = (params) => createRule((value, ctx) => {
|
16
|
+
if (!value.start || !value.end) {
|
17
|
+
return undefined;
|
18
|
+
}
|
19
|
+
if (!isDate(value.start) || !isDate(value.end)) {
|
20
|
+
return undefined;
|
21
|
+
}
|
22
|
+
if (isDateEqual(value.start, value.end)) {
|
23
|
+
return ctx.createError({
|
24
|
+
message: (params === null || params === void 0 ? void 0 : params.message) || RANGE_DATE_NOT_EQUAL_ERROR_INFO.message,
|
25
|
+
code: RANGE_DATE_NOT_EQUAL_ERROR_INFO.code,
|
26
|
+
});
|
27
|
+
}
|
28
|
+
return undefined;
|
29
|
+
});
|