@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.
Files changed (38) hide show
  1. package/README.md +153 -0
  2. package/core/utils/index.d.ts +5 -4
  3. package/core/utils/index.js +5 -4
  4. package/core/utils/isDateEarlier/index.d.ts +1 -0
  5. package/core/utils/isDateEarlier/index.js +1 -0
  6. package/core/utils/isDateEarlier/isDateEarlier.d.ts +1 -0
  7. package/core/utils/isDateEarlier/isDateEarlier.js +4 -0
  8. package/index.d.ts +4 -0
  9. package/index.js +4 -0
  10. package/package.json +3 -2
  11. package/rangeDate/constants.d.ts +7 -0
  12. package/rangeDate/constants.js +25 -0
  13. package/rangeDate/index.d.ts +2 -0
  14. package/rangeDate/index.js +2 -0
  15. package/rangeDate/rangeDate.d.ts +48 -0
  16. package/rangeDate/rangeDate.js +60 -0
  17. package/rangeDateInterval/constants.d.ts +7 -0
  18. package/rangeDateInterval/constants.js +14 -0
  19. package/rangeDateInterval/index.d.ts +2 -0
  20. package/rangeDateInterval/index.js +2 -0
  21. package/rangeDateInterval/rangeDateInterval.d.ts +23 -0
  22. package/rangeDateInterval/rangeDateInterval.js +36 -0
  23. package/rangeDateInterval/types.d.ts +6 -0
  24. package/rangeDateInterval/types.js +1 -0
  25. package/rangeDateMinMax/constants.d.ts +8 -0
  26. package/rangeDateMinMax/constants.js +13 -0
  27. package/rangeDateMinMax/index.d.ts +2 -0
  28. package/rangeDateMinMax/index.js +2 -0
  29. package/rangeDateMinMax/rangeDateMinMax.d.ts +34 -0
  30. package/rangeDateMinMax/rangeDateMinMax.js +74 -0
  31. package/rangeDateMinMax/types.d.ts +2 -0
  32. package/rangeDateMinMax/types.js +1 -0
  33. package/rangeDateNotEqual/constants.d.ts +2 -0
  34. package/rangeDateNotEqual/constants.js +5 -0
  35. package/rangeDateNotEqual/index.d.ts +2 -0
  36. package/rangeDateNotEqual/index.js +2 -0
  37. package/rangeDateNotEqual/rangeDateNotEqual.d.ts +20 -0
  38. 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
  - Возвращает ошибку если:
@@ -1,7 +1,8 @@
1
- export * from './isStringOfZeros';
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 './isHasConsecutiveChars';
6
- export * from './isFullNameValidCharacters';
6
+ export * from './isStringOfZeros';
7
7
  export * from './isValidFullNameLength';
8
+ export * from './resetTime';
@@ -1,7 +1,8 @@
1
- export * from './isStringOfZeros';
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 './isHasConsecutiveChars';
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;
@@ -0,0 +1,4 @@
1
+ import { resetTime } from '../resetTime';
2
+ export const isDateEarlier = (dateA, dateB) => {
3
+ return resetTime(dateA).getTime() < resetTime(dateB).getTime();
4
+ };
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.14.6",
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,2 @@
1
+ export * from './constants';
2
+ export * from './rangeDate';
@@ -0,0 +1,2 @@
1
+ export * from './constants';
2
+ export * from './rangeDate';
@@ -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,7 @@
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_INTERVAL_ERROR_INFO: DynamicErrorInfo;
7
+ export {};
@@ -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,2 @@
1
+ export * from './constants';
2
+ export * from './rangeDateInterval';
@@ -0,0 +1,2 @@
1
+ export * from './constants';
2
+ export * from './rangeDateInterval';
@@ -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,6 @@
1
+ export type RangeDateValue = {
2
+ start?: Date;
3
+ end?: Date;
4
+ };
5
+ export type DateUnit = 'day' | 'month' | 'year';
6
+ export type DefaultMessage = (limit: number, unit: DateUnit) => string;
@@ -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,2 @@
1
+ export * from './constants';
2
+ export * from './rangeDateMinMax';
@@ -0,0 +1,2 @@
1
+ export * from './constants';
2
+ export * from './rangeDateMinMax';
@@ -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,2 @@
1
+ export type Field = 'start' | 'end';
2
+ export type DefaultMessage = (field: Field, date: string) => string;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import { type ErrorInfo } from '../core';
2
+ export declare const RANGE_DATE_NOT_EQUAL_ERROR_INFO: ErrorInfo;
@@ -0,0 +1,5 @@
1
+ import { createErrorCode } from '../core';
2
+ export const RANGE_DATE_NOT_EQUAL_ERROR_INFO = {
3
+ code: createErrorCode('rangedate-notequal'),
4
+ message: 'Даты начала и окончания не могут совпадать',
5
+ };
@@ -0,0 +1,2 @@
1
+ export * from './constants';
2
+ export * from './rangeDateNotEqual';
@@ -0,0 +1,2 @@
1
+ export * from './constants';
2
+ export * from './rangeDateNotEqual';
@@ -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
+ });