@azure-net/kit 0.8.5 → 0.8.8
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/dist/core/delivery/schema/Schema.d.ts +33 -0
- package/dist/core/delivery/schema/Schema.js +78 -0
- package/dist/core/delivery/schema/index.d.ts +1 -0
- package/dist/core/delivery/schema/index.js +1 -0
- package/dist/core/delivery/schema/rules/Rules.d.ts +59 -0
- package/dist/core/delivery/schema/rules/Rules.js +285 -0
- package/dist/core/delivery/schema/rules/messages/En.d.ts +2 -0
- package/dist/core/delivery/schema/rules/messages/En.js +40 -0
- package/dist/core/delivery/schema/rules/messages/Ru.d.ts +2 -0
- package/dist/core/delivery/schema/rules/messages/Ru.js +40 -0
- package/dist/core/delivery/schema/rules/messages/WithI18n.d.ts +2 -0
- package/dist/core/delivery/schema/rules/messages/WithI18n.js +40 -0
- package/dist/core/delivery/schema/rules/messages/index.d.ts +3 -0
- package/dist/core/delivery/schema/rules/messages/index.js +3 -0
- package/dist/core/delivery/schema/rules/messages/types.d.ts +41 -0
- package/dist/core/delivery/schema/rules/messages/types.js +1 -0
- package/dist/core/delivery/serverAction/CreateServerAction.d.ts +1 -1
- package/dist/core/delivery/serverAction/CreateServerAction.js +3 -3
- package/dist/core/index.d.ts +3 -5
- package/dist/core/index.js +3 -5
- package/dist/core/infra/index.d.ts +5 -0
- package/dist/core/infra/index.js +5 -0
- package/dist/core/infra/response/BaseResponse.d.ts +1 -1
- package/dist/core/infra/response/BaseResponse.js +0 -1
- package/dist/core/shared/boundaryProvider/Provider.js +6 -6
- package/dist/core/shared/cookie/UniversalCookie.d.ts +69 -0
- package/dist/core/shared/cookie/UniversalCookie.js +157 -0
- package/dist/core/shared/cookie/index.d.ts +1 -0
- package/dist/core/shared/cookie/index.js +1 -0
- package/dist/core/shared/eventBus/EventBus.d.ts +6 -10
- package/dist/core/shared/eventBus/EventBus.js +12 -18
- package/dist/core/shared/middleware/Middleware.d.ts +16 -0
- package/dist/core/shared/middleware/Middleware.js +68 -0
- package/dist/core/shared/middleware/index.d.ts +1 -0
- package/dist/core/shared/middleware/index.js +1 -0
- package/dist/{lib → core/ui}/onClickOutside/OnClickOutside.js +2 -2
- package/dist/svelte/AsyncSignal/AsyncSignal.svelte.js +4 -4
- package/package.json +7 -6
- /package/dist/{lib → core/ui}/eventModifiers/EventModifiers.d.ts +0 -0
- /package/dist/{lib → core/ui}/eventModifiers/EventModifiers.js +0 -0
- /package/dist/{lib → core/ui}/eventModifiers/index.d.ts +0 -0
- /package/dist/{lib → core/ui}/eventModifiers/index.js +0 -0
- /package/dist/{lib → core/ui}/index.d.ts +0 -0
- /package/dist/{lib → core/ui}/index.js +0 -0
- /package/dist/{lib → core/ui}/onClickOutside/OnClickOutside.d.ts +0 -0
- /package/dist/{lib → core/ui}/onClickOutside/index.d.ts +0 -0
- /package/dist/{lib → core/ui}/onClickOutside/index.js +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
type DeepKeys<T> = T extends object ? {
|
|
2
|
+
[K in keyof T & string]: T[K] extends object ? K | `${K}.${DeepKeys<T[K]>}` : K;
|
|
3
|
+
}[keyof T & string] : never;
|
|
4
|
+
export type ValidationParams<T = unknown, V = unknown, K = string> = {
|
|
5
|
+
val: V;
|
|
6
|
+
listValues?: Partial<T>;
|
|
7
|
+
key?: K;
|
|
8
|
+
};
|
|
9
|
+
export type ValidationMessage = string | {
|
|
10
|
+
key: string;
|
|
11
|
+
vars?: Record<string, unknown>;
|
|
12
|
+
};
|
|
13
|
+
export interface ValidationErrorsMap {
|
|
14
|
+
[key: string]: ValidationMessage | ValidationErrorsMap;
|
|
15
|
+
}
|
|
16
|
+
export type ValidationResult = ValidationMessage | ValidationErrorsMap | ValidationErrorsMap[] | undefined;
|
|
17
|
+
export type ValidationRuleResult<CurrentValue, ListValues = unknown, CurrentKey = string> = (params: ValidationParams<CurrentValue, ListValues, CurrentKey>) => ValidationResult;
|
|
18
|
+
type ValidationErrors<T> = T extends ReadonlyArray<infer U> ? ValidationErrors<U>[] : T extends object ? {
|
|
19
|
+
[K in keyof T]?: ValidationErrors<T[K]>;
|
|
20
|
+
} : ValidationMessage;
|
|
21
|
+
export type RequestErrors<Dict> = Partial<ValidationErrors<Dict>>;
|
|
22
|
+
export type RequestRules<D> = Partial<Record<DeepKeys<D>, ValidationRuleResult<D>[]>>;
|
|
23
|
+
export declare const createSchemaFactory: <Rules>(rulesList: Rules) => <IncomingData, DataAfterTransform = IncomingData>(params: {
|
|
24
|
+
schema: (rules: Rules) => RequestRules<IncomingData>;
|
|
25
|
+
transform: (data: IncomingData) => DataAfterTransform;
|
|
26
|
+
}) => {
|
|
27
|
+
from: (data: IncomingData) => void;
|
|
28
|
+
json: () => DataAfterTransform;
|
|
29
|
+
formData: () => FormData;
|
|
30
|
+
validate: () => undefined;
|
|
31
|
+
readonly errors: Partial<ValidationErrors<IncomingData>>;
|
|
32
|
+
};
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { FormDataUtil } from 'azure-net-tools';
|
|
2
|
+
export const createSchemaFactory = (rulesList) => {
|
|
3
|
+
return (params) => {
|
|
4
|
+
let schemaData;
|
|
5
|
+
let _errors = {};
|
|
6
|
+
let _isValid = true;
|
|
7
|
+
const { schema, transform = (data) => data } = params;
|
|
8
|
+
const definedSchema = schema(rulesList);
|
|
9
|
+
const getByPath = (path) => {
|
|
10
|
+
return path.split('.').reduce((o, k) => (o && typeof o === 'object' ? o[k] : undefined), schemaData);
|
|
11
|
+
};
|
|
12
|
+
const setByPath = (obj, path, value) => {
|
|
13
|
+
const keys = path.split('.');
|
|
14
|
+
let current = obj;
|
|
15
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
16
|
+
const k = keys[i];
|
|
17
|
+
if (!(k in current) || typeof current[k] !== 'object') {
|
|
18
|
+
current[k] = {};
|
|
19
|
+
}
|
|
20
|
+
current = current[k];
|
|
21
|
+
}
|
|
22
|
+
current[keys[(keys.length - 1)]] = value;
|
|
23
|
+
};
|
|
24
|
+
const prepare = (dataToPrepare) => {
|
|
25
|
+
if (dataToPrepare instanceof FormData) {
|
|
26
|
+
return FormDataUtil.toObject(dataToPrepare);
|
|
27
|
+
}
|
|
28
|
+
return dataToPrepare;
|
|
29
|
+
};
|
|
30
|
+
const validate = () => {
|
|
31
|
+
_isValid = true;
|
|
32
|
+
_errors = {};
|
|
33
|
+
if (typeof schemaData !== 'object') {
|
|
34
|
+
throw Error('Data to validate is not an object');
|
|
35
|
+
}
|
|
36
|
+
for (const key in definedSchema) {
|
|
37
|
+
const fieldRules = definedSchema[key] ?? [];
|
|
38
|
+
const value = getByPath(key);
|
|
39
|
+
for (const rule of fieldRules) {
|
|
40
|
+
const failMessage = rule({
|
|
41
|
+
val: value,
|
|
42
|
+
listValues: schemaData,
|
|
43
|
+
key: key
|
|
44
|
+
});
|
|
45
|
+
if (failMessage) {
|
|
46
|
+
setByPath(_errors, key, failMessage);
|
|
47
|
+
_isValid = false;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (!_isValid) {
|
|
53
|
+
throw this;
|
|
54
|
+
}
|
|
55
|
+
return this;
|
|
56
|
+
};
|
|
57
|
+
const from = (data) => {
|
|
58
|
+
schemaData = prepare(data);
|
|
59
|
+
};
|
|
60
|
+
const formData = () => {
|
|
61
|
+
validate();
|
|
62
|
+
return FormDataUtil.fromObject(transform(schemaData));
|
|
63
|
+
};
|
|
64
|
+
const json = () => {
|
|
65
|
+
validate();
|
|
66
|
+
return transform(schemaData);
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
from,
|
|
70
|
+
json,
|
|
71
|
+
formData,
|
|
72
|
+
validate,
|
|
73
|
+
get errors() {
|
|
74
|
+
return _errors;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Schema.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Schema.js';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { BaseValidationMessages } from './messages/types.js';
|
|
2
|
+
import type { ValidationParams, ValidationRuleResult } from '../index.js';
|
|
3
|
+
import { type CountryCode } from 'libphonenumber-js';
|
|
4
|
+
export type ValidationRuleParams<T extends keyof BaseValidationMessages, D = object> = D & {
|
|
5
|
+
message?: BaseValidationMessages[T];
|
|
6
|
+
};
|
|
7
|
+
export type LengthParams = {
|
|
8
|
+
length?: {
|
|
9
|
+
min?: number;
|
|
10
|
+
max?: number;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
export type RangeParams = {
|
|
14
|
+
range?: {
|
|
15
|
+
min?: number;
|
|
16
|
+
max?: number;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
type ArrayItemRules<Context> = ValidationRuleResult<Context>[] | Record<string, ValidationRuleResult<Context>[]>;
|
|
20
|
+
type ArrayParams<Context> = LengthParams & {
|
|
21
|
+
schema?: ArrayItemRules<Context>;
|
|
22
|
+
};
|
|
23
|
+
export declare const createRules: <M extends BaseValidationMessages>(validationMessages: M) => {
|
|
24
|
+
string: <T = unknown, D = unknown>(params?: ValidationRuleParams<"string", LengthParams>) => ValidationRuleResult<T, D>;
|
|
25
|
+
number: <T = unknown, D_1 = unknown>(params?: ValidationRuleParams<"number", RangeParams>) => ValidationRuleResult<T, D_1>;
|
|
26
|
+
required: <T = unknown, D_2 = unknown, J = unknown>(params?: ValidationRuleParams<"required", {
|
|
27
|
+
byCondition?: (params: ValidationParams<T, D_2, J>) => boolean;
|
|
28
|
+
}>) => ValidationRuleResult<T, D_2, J>;
|
|
29
|
+
password: <T = unknown, D_3 = unknown>(params?: ValidationRuleParams<"password", {
|
|
30
|
+
length?: number;
|
|
31
|
+
specialChars?: boolean | number;
|
|
32
|
+
numbers?: boolean | number;
|
|
33
|
+
lowerUpperCasePattern?: boolean;
|
|
34
|
+
}>) => ValidationRuleResult<T, D_3>;
|
|
35
|
+
notSameAs: <T = unknown, D_4 = unknown>(params: ValidationRuleParams<"sameAs", {
|
|
36
|
+
key: keyof T | string;
|
|
37
|
+
}>) => ValidationRuleResult<T, D_4>;
|
|
38
|
+
sameAs: <T = unknown, D_5 = unknown>(params: ValidationRuleParams<"sameAs", {
|
|
39
|
+
key: keyof T | string;
|
|
40
|
+
}>) => ValidationRuleResult<T, D_5>;
|
|
41
|
+
array: <T = unknown>(params?: ValidationRuleParams<"array", ArrayParams<T>>) => ValidationRuleResult<T>;
|
|
42
|
+
boolean: <T = unknown, D_6 = unknown>(params?: ValidationRuleParams<"boolean", {
|
|
43
|
+
expected?: boolean;
|
|
44
|
+
}>) => ValidationRuleResult<T, D_6>;
|
|
45
|
+
email: <T = unknown, D_7 = unknown>(params?: ValidationRuleParams<"email">) => ValidationRuleResult<T, D_7>;
|
|
46
|
+
finite: <T = unknown, D_8 = unknown>(params?: ValidationRuleParams<"finite", RangeParams & {
|
|
47
|
+
maxDigitsAfterDot?: number;
|
|
48
|
+
}>) => ValidationRuleResult<T, D_8>;
|
|
49
|
+
lettersOnly: <T = unknown, D_9 = unknown>(params?: ValidationRuleParams<"lettersOnly", {
|
|
50
|
+
whiteSpaces?: boolean;
|
|
51
|
+
}>) => ValidationRuleResult<T, D_9>;
|
|
52
|
+
phone: <T = unknown, D_10 = unknown>(params?: ValidationRuleParams<"phone", {
|
|
53
|
+
country: CountryCode;
|
|
54
|
+
}>) => ValidationRuleResult<T, D_10>;
|
|
55
|
+
allowedOnly: <T = unknown, D_11 = unknown>(params?: ValidationRuleParams<"allowedOnly", {
|
|
56
|
+
allowed?: unknown[];
|
|
57
|
+
}>) => ValidationRuleResult<T, D_11>;
|
|
58
|
+
};
|
|
59
|
+
export {};
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { isValidNumber } from 'libphonenumber-js';
|
|
2
|
+
export const createRules = (validationMessages) => {
|
|
3
|
+
const checkVal = (val) => {
|
|
4
|
+
return val !== undefined && val !== null;
|
|
5
|
+
};
|
|
6
|
+
const string = (params) => {
|
|
7
|
+
const { message, length } = { ...params, message: { ...validationMessages.string, ...params?.message } };
|
|
8
|
+
return ({ val }) => {
|
|
9
|
+
if (checkVal(val)) {
|
|
10
|
+
if (typeof val !== 'string') {
|
|
11
|
+
return message.base();
|
|
12
|
+
}
|
|
13
|
+
switch (true) {
|
|
14
|
+
case length && checkVal(length.min) && val.length < length.min:
|
|
15
|
+
return message.min(length.min);
|
|
16
|
+
case length && checkVal(length.max) && val.length > length.max:
|
|
17
|
+
return message.max(length.max);
|
|
18
|
+
default:
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
const number = (params) => {
|
|
26
|
+
const { message, range } = { ...params, message: { ...validationMessages.number, ...params?.message } };
|
|
27
|
+
return ({ val }) => {
|
|
28
|
+
if (checkVal(val)) {
|
|
29
|
+
const numberVal = Number(val);
|
|
30
|
+
if (!Number.isInteger(numberVal) || Number.isNaN(numberVal)) {
|
|
31
|
+
return message.base();
|
|
32
|
+
}
|
|
33
|
+
switch (true) {
|
|
34
|
+
case range && checkVal(range?.min) && numberVal < range.min:
|
|
35
|
+
return message.min(range.min);
|
|
36
|
+
case range && checkVal(range?.max) && numberVal > range.max:
|
|
37
|
+
return message.max(range.max);
|
|
38
|
+
default:
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return undefined;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
const finite = (params) => {
|
|
46
|
+
const { message, maxDigitsAfterDot, range } = { ...params, message: { ...validationMessages.finite, ...params?.message } };
|
|
47
|
+
return ({ val }) => {
|
|
48
|
+
if (checkVal(val)) {
|
|
49
|
+
const numVal = Number(val);
|
|
50
|
+
if (!Number.isFinite(numVal) || String(val)[0] === '.') {
|
|
51
|
+
return message.base();
|
|
52
|
+
}
|
|
53
|
+
if (typeof maxDigitsAfterDot === 'number') {
|
|
54
|
+
const digitsAfterDot = val.toString().split('.')[1]?.length ?? 0;
|
|
55
|
+
if (digitsAfterDot > maxDigitsAfterDot) {
|
|
56
|
+
return message.maxDigitsAfterDot(maxDigitsAfterDot);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (range?.min !== undefined && numVal < range.min)
|
|
60
|
+
return message.min(range.min);
|
|
61
|
+
if (range?.max !== undefined && numVal > range.max)
|
|
62
|
+
return message.max(range.max);
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
return undefined;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
const boolean = (params) => {
|
|
69
|
+
const { message, expected } = { ...params, message: { ...validationMessages.boolean, ...params?.message } };
|
|
70
|
+
return ({ val }) => {
|
|
71
|
+
if (checkVal(val)) {
|
|
72
|
+
if (typeof val !== 'boolean')
|
|
73
|
+
return message.base();
|
|
74
|
+
if (expected !== undefined && val !== expected)
|
|
75
|
+
return message.expected(String(expected));
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
const array = (params) => {
|
|
82
|
+
const { message, length = {}, schema } = { ...params, message: { ...validationMessages.array, ...params?.message } };
|
|
83
|
+
return ({ val, listValues, key }) => {
|
|
84
|
+
if (checkVal(val)) {
|
|
85
|
+
if (!Array.isArray(val))
|
|
86
|
+
return message.base();
|
|
87
|
+
if (length.min && val.length < length.min)
|
|
88
|
+
return message.min(length.min);
|
|
89
|
+
if (length.max && val.length > length.max)
|
|
90
|
+
return message.max(length.max);
|
|
91
|
+
if (schema) {
|
|
92
|
+
const nestedErrors = [];
|
|
93
|
+
for (let index = 0; index < val.length; index++) {
|
|
94
|
+
const element = val[index];
|
|
95
|
+
const itemErrors = {};
|
|
96
|
+
if (Array.isArray(schema)) {
|
|
97
|
+
for (const rule of schema) {
|
|
98
|
+
const fail = rule({
|
|
99
|
+
val: element,
|
|
100
|
+
listValues,
|
|
101
|
+
key: `${key}[${index}]`
|
|
102
|
+
});
|
|
103
|
+
if (fail) {
|
|
104
|
+
itemErrors['_error'] = fail;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if (typeof schema === 'object' && schema !== null) {
|
|
110
|
+
if (typeof element !== 'object' || element === null) {
|
|
111
|
+
itemErrors['_error'] = message.base();
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
for (const fieldKey in schema) {
|
|
115
|
+
const fieldRules = schema[fieldKey] ?? [];
|
|
116
|
+
const fieldValue = element?.[fieldKey];
|
|
117
|
+
for (const rule of fieldRules) {
|
|
118
|
+
const fail = rule({
|
|
119
|
+
val: fieldValue,
|
|
120
|
+
listValues,
|
|
121
|
+
key: `${key}[${index}].${fieldKey}`
|
|
122
|
+
});
|
|
123
|
+
if (fail) {
|
|
124
|
+
itemErrors[fieldKey] = fail;
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
nestedErrors[index] = itemErrors;
|
|
132
|
+
}
|
|
133
|
+
if (nestedErrors.some((e) => Object.keys(e).length > 0)) {
|
|
134
|
+
return nestedErrors;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return undefined;
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
const phone = (params) => {
|
|
142
|
+
const { message, country = 'RU' } = { ...params, message: params?.message ?? validationMessages.phone };
|
|
143
|
+
return ({ val }) => {
|
|
144
|
+
if (checkVal(val)) {
|
|
145
|
+
return isValidNumber(String(val), country) ? undefined : message();
|
|
146
|
+
}
|
|
147
|
+
return undefined;
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
const email = (params) => {
|
|
151
|
+
const { message } = { message: params?.message ?? validationMessages.email };
|
|
152
|
+
const emailRegExp =
|
|
153
|
+
// eslint-disable-next-line no-control-regex
|
|
154
|
+
/^(?:[A-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|[\x01-\x09\x0B\x0C\x0E-\x7F])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]{2,}(?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21-\x5A\x53-\x7F]|\\[\x01-\x09\x0B\x0C\x0E-\x7F])+)])$/i;
|
|
155
|
+
return ({ val }) => {
|
|
156
|
+
if (checkVal(val)) {
|
|
157
|
+
const stringedVal = typeof val === 'string' ? String(val) : undefined;
|
|
158
|
+
return stringedVal && emailRegExp.test(stringedVal) ? undefined : message();
|
|
159
|
+
}
|
|
160
|
+
return undefined;
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
const lettersOnly = (params) => {
|
|
164
|
+
const { message, whiteSpaces = false } = { ...params, message: params?.message ?? validationMessages.lettersOnly };
|
|
165
|
+
const lettersRegex = whiteSpaces ? /^[а-яА-Яa-zA-Z\s]+$/ : /^[а-яА-Яa-zA-Z]+$/;
|
|
166
|
+
return ({ val }) => {
|
|
167
|
+
if (checkVal(val)) {
|
|
168
|
+
const stringedVal = typeof val === 'string' ? String(val) : undefined;
|
|
169
|
+
return stringedVal && lettersRegex.test(stringedVal) ? undefined : message(whiteSpaces);
|
|
170
|
+
}
|
|
171
|
+
return undefined;
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
const allowedOnly = (params) => {
|
|
175
|
+
const { message, allowed } = { ...params, message: params?.message ?? validationMessages.allowedOnly };
|
|
176
|
+
return ({ val }) => {
|
|
177
|
+
if (checkVal(val)) {
|
|
178
|
+
switch (true) {
|
|
179
|
+
case !!allowed && Array.isArray(allowed):
|
|
180
|
+
if (!allowed?.length) {
|
|
181
|
+
return message('');
|
|
182
|
+
}
|
|
183
|
+
return allowed.includes(val) ? undefined : message(allowed.join(', '));
|
|
184
|
+
default:
|
|
185
|
+
return undefined;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return undefined;
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
const sameAs = (params) => {
|
|
192
|
+
const { message, key } = { ...params, message: params?.message ?? validationMessages.sameAs };
|
|
193
|
+
return ({ val, listValues }) => {
|
|
194
|
+
if (checkVal(val)) {
|
|
195
|
+
switch (true) {
|
|
196
|
+
case typeof val === 'object':
|
|
197
|
+
if (!listValues?.[key] || typeof listValues[key] !== 'object') {
|
|
198
|
+
return message(String(key));
|
|
199
|
+
}
|
|
200
|
+
try {
|
|
201
|
+
return JSON.stringify(val) === JSON.stringify(listValues[key]) ? undefined : message(String(key));
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
default:
|
|
207
|
+
return String(val ?? '') === String(listValues?.[key] ?? '') ? undefined : message(String(key));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return undefined;
|
|
211
|
+
};
|
|
212
|
+
};
|
|
213
|
+
const notSameAs = (params) => {
|
|
214
|
+
const { message, key } = { ...params, message: params?.message ?? validationMessages.notSameAs };
|
|
215
|
+
return ({ val, listValues }) => {
|
|
216
|
+
if (checkVal(val)) {
|
|
217
|
+
switch (true) {
|
|
218
|
+
case typeof val === 'object':
|
|
219
|
+
if (!listValues?.[key] || typeof listValues[key] !== 'object') {
|
|
220
|
+
return message(String(key));
|
|
221
|
+
}
|
|
222
|
+
try {
|
|
223
|
+
return JSON.stringify(val) !== JSON.stringify(listValues[key]) ? undefined : message(String(key));
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
228
|
+
default:
|
|
229
|
+
return String(val) === String(listValues?.[key]) ? undefined : message(String(key));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return undefined;
|
|
233
|
+
};
|
|
234
|
+
};
|
|
235
|
+
const required = (params) => {
|
|
236
|
+
const { message, byCondition } = { ...params, message: params?.message ?? validationMessages.required };
|
|
237
|
+
return ({ val, listValues, key }) => {
|
|
238
|
+
if (!checkVal(val))
|
|
239
|
+
return message();
|
|
240
|
+
if (byCondition && !byCondition({ val, listValues, key }))
|
|
241
|
+
return undefined;
|
|
242
|
+
if (typeof val === 'string' && !val.length)
|
|
243
|
+
return message();
|
|
244
|
+
if (val instanceof File && val.size < 1)
|
|
245
|
+
return message();
|
|
246
|
+
if (typeof val === 'number' && !String(val).length)
|
|
247
|
+
return message();
|
|
248
|
+
return undefined;
|
|
249
|
+
};
|
|
250
|
+
};
|
|
251
|
+
const password = (params) => {
|
|
252
|
+
const { message, length = 8, specialChars, numbers, lowerUpperCasePattern } = { ...params, message: { ...validationMessages.password, ...params?.message } };
|
|
253
|
+
return ({ val }) => {
|
|
254
|
+
if (!checkVal(val))
|
|
255
|
+
return undefined;
|
|
256
|
+
const str = String(val);
|
|
257
|
+
if (str.length < length) {
|
|
258
|
+
return message.length(length);
|
|
259
|
+
}
|
|
260
|
+
if (specialChars) {
|
|
261
|
+
const minCount = typeof specialChars === 'number' ? specialChars : 1;
|
|
262
|
+
const count = (str.match(/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/g) || []).length;
|
|
263
|
+
if (count < minCount) {
|
|
264
|
+
return message.specialChars(minCount);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (numbers) {
|
|
268
|
+
const minCount = typeof numbers === 'number' ? numbers : 1;
|
|
269
|
+
const count = (str.match(/[0-9]/g) || []).length;
|
|
270
|
+
if (count < minCount) {
|
|
271
|
+
return message.numbers(minCount);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (lowerUpperCasePattern) {
|
|
275
|
+
const hasLower = /[a-z]/.test(str);
|
|
276
|
+
const hasUpper = /[A-Z]/.test(str);
|
|
277
|
+
if (!hasLower || !hasUpper) {
|
|
278
|
+
return message.lowerUpperCasePattern();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return undefined;
|
|
282
|
+
};
|
|
283
|
+
};
|
|
284
|
+
return { string, number, required, password, notSameAs, sameAs, array, boolean, email, finite, lettersOnly, phone, allowedOnly };
|
|
285
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export const validationMessagesEn = {
|
|
2
|
+
phone: () => 'Invalid phone number format',
|
|
3
|
+
email: () => 'Invalid email address',
|
|
4
|
+
required: () => 'This field is required',
|
|
5
|
+
lettersOnly: (whiteSpaces) => `This field may contain letters only${whiteSpaces ? '' : ' and must not contain spaces'}`,
|
|
6
|
+
allowedOnly: (value) => value && value.length ? `This field may contain only one of the following values: ${value}` : 'This field has no allowed values',
|
|
7
|
+
sameAs: (value) => `This field must match the ${value} field`,
|
|
8
|
+
notSameAs: (value) => `This field must not match the ${value} field`,
|
|
9
|
+
boolean: {
|
|
10
|
+
base: () => 'This field must be a boolean value',
|
|
11
|
+
expected: (value) => `Expected value: ${value}`
|
|
12
|
+
},
|
|
13
|
+
finite: {
|
|
14
|
+
base: () => 'This field must be a number',
|
|
15
|
+
min: (value) => `The number must be at least ${value}`,
|
|
16
|
+
max: (value) => `The number must be at most ${value}`,
|
|
17
|
+
maxDigitsAfterDot: (value) => `Number of digits after the decimal point must not exceed ${value}`
|
|
18
|
+
},
|
|
19
|
+
number: {
|
|
20
|
+
base: () => 'This field must be an integer',
|
|
21
|
+
min: (value) => `The number must be at least ${value}`,
|
|
22
|
+
max: (value) => `The number must be at most ${value}`
|
|
23
|
+
},
|
|
24
|
+
string: {
|
|
25
|
+
base: () => 'This field must be a string',
|
|
26
|
+
min: (value) => `Minimum string length is ${value}`,
|
|
27
|
+
max: (value) => `Maximum string length is ${value}`
|
|
28
|
+
},
|
|
29
|
+
array: {
|
|
30
|
+
base: () => 'This field must be an array',
|
|
31
|
+
min: (value) => `Minimum array length is ${value}`,
|
|
32
|
+
max: (value) => `Maximum array length is ${value}`
|
|
33
|
+
},
|
|
34
|
+
password: {
|
|
35
|
+
length: (value) => `Minimum password length is ${value}`,
|
|
36
|
+
specialChars: (value) => `Password must contain at least ${value} special character(s)`,
|
|
37
|
+
lowerUpperCasePattern: () => 'Password must contain both uppercase and lowercase letters',
|
|
38
|
+
numbers: (value) => `Password must contain at least ${value} number(s)`
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export const validationMessagesRu = {
|
|
2
|
+
phone: () => 'Неверный формат номера телефона',
|
|
3
|
+
email: () => 'Невалидный email',
|
|
4
|
+
required: () => 'Поле обязательно к заполнению',
|
|
5
|
+
lettersOnly: (whiteSpaces) => `Поле может содержать только буквы ${whiteSpaces ? '' : 'и не должно содержать пробелы'}`,
|
|
6
|
+
allowedOnly: (value) => value && value.length ? `Поле может содержать только одно из следующих значений:: ${value}` : 'Поле не имеет допустимых значений',
|
|
7
|
+
sameAs: (value) => `Поле должно совпадать с полем ${value}`,
|
|
8
|
+
notSameAs: (value) => `Поле не должно совпадать с полем ${value}`,
|
|
9
|
+
boolean: {
|
|
10
|
+
base: () => 'Поле должно содержать значение типа boolean',
|
|
11
|
+
expected: (value) => `Ожидаемое значение поля - ${value}`
|
|
12
|
+
},
|
|
13
|
+
finite: {
|
|
14
|
+
base: () => 'Поле должно быть числом',
|
|
15
|
+
min: (value) => `Число должно быть не менее ${value}`,
|
|
16
|
+
max: (value) => `Число должно быть не более ${value}`,
|
|
17
|
+
maxDigitsAfterDot: (value) => `Количество символов после точки не более ${value}`
|
|
18
|
+
},
|
|
19
|
+
number: {
|
|
20
|
+
base: () => 'Поле должно быть целым числом',
|
|
21
|
+
min: (value) => `Число должно быть не менее ${value}`,
|
|
22
|
+
max: (value) => `Число должно быть не более ${value}`
|
|
23
|
+
},
|
|
24
|
+
string: {
|
|
25
|
+
base: () => 'Поле должно быть строкой',
|
|
26
|
+
min: (value) => `Минимальная длина строки - ${value}`,
|
|
27
|
+
max: (value) => `Максимальная длина строки - ${value}`
|
|
28
|
+
},
|
|
29
|
+
array: {
|
|
30
|
+
base: () => 'Поле должно быть массивом',
|
|
31
|
+
min: (value) => `Минимальная длина массива - ${value}`,
|
|
32
|
+
max: (value) => `Максимальная длина массива - ${value}`
|
|
33
|
+
},
|
|
34
|
+
password: {
|
|
35
|
+
length: (value) => `Минимальная длина пароля - ${value}`,
|
|
36
|
+
specialChars: (value) => `В пароле должно быть спецсимволы в количестве не менее ${value}`,
|
|
37
|
+
lowerUpperCasePattern: () => 'В пароле должны быть буквы верхнего и нижнего регистра',
|
|
38
|
+
numbers: (value) => `В пароле должно быть цифры в количестве не менее ${value}`
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export const validationMessagesI18n = {
|
|
2
|
+
phone: () => 'validation.phone',
|
|
3
|
+
email: () => 'validation.email',
|
|
4
|
+
required: () => 'validation.required',
|
|
5
|
+
lettersOnly: (whiteSpaces) => (whiteSpaces ? 'validation.lettersOnlyWithWhiteSpaces' : 'validation.lettersOnly'),
|
|
6
|
+
allowedOnly: (value) => ({ key: value && value.length ? 'validation.allowedOnly.base' : 'validation.allowedOnly.nothing', vars: { value } }),
|
|
7
|
+
sameAs: (value) => ({ key: 'validation.sameAs', vars: { value } }),
|
|
8
|
+
notSameAs: (value) => ({ key: 'validation.notSameAs', vars: { value } }),
|
|
9
|
+
boolean: {
|
|
10
|
+
base: () => 'validation.boolean.base',
|
|
11
|
+
expected: (value) => ({ key: 'validation.boolean.expected', vars: { value } })
|
|
12
|
+
},
|
|
13
|
+
finite: {
|
|
14
|
+
base: () => 'validation.finite.base',
|
|
15
|
+
min: (value) => ({ key: 'validation.finite.minLength', vars: { value } }),
|
|
16
|
+
max: (value) => ({ key: 'validation.finite.maxLength', vars: { value } }),
|
|
17
|
+
maxDigitsAfterDot: (value) => ({ key: 'validation.finite.maxDigitsAfterDot', vars: { value } })
|
|
18
|
+
},
|
|
19
|
+
number: {
|
|
20
|
+
base: () => 'validation.number.base',
|
|
21
|
+
min: (value) => ({ key: 'validation.number.minLength', vars: { value } }),
|
|
22
|
+
max: (value) => ({ key: 'validation.number.maxLength', vars: { value } })
|
|
23
|
+
},
|
|
24
|
+
string: {
|
|
25
|
+
base: () => 'validation.string.base',
|
|
26
|
+
min: (value) => ({ key: 'validation.string.minLength', vars: { value } }),
|
|
27
|
+
max: (value) => ({ key: 'validation.string.maxLength', vars: { value } })
|
|
28
|
+
},
|
|
29
|
+
array: {
|
|
30
|
+
base: () => 'validation.array.base',
|
|
31
|
+
min: (value) => ({ key: 'validation.array.minLength', vars: { value } }),
|
|
32
|
+
max: (value) => ({ key: 'validation.array.maxLength', vars: { value } })
|
|
33
|
+
},
|
|
34
|
+
password: {
|
|
35
|
+
length: (value) => ({ key: 'validation.password.length', vars: { value } }),
|
|
36
|
+
specialChars: (value) => ({ key: 'validation.password.specialChars', vars: { value } }),
|
|
37
|
+
lowerUpperCasePattern: () => ({ key: 'validation.password.lowerUpperCasePattern' }),
|
|
38
|
+
numbers: (value) => ({ key: 'validation.password.numbers', vars: { value } })
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ValidationMessage } from '../../index.js';
|
|
2
|
+
export type BaseValidationMessages = {
|
|
3
|
+
phone: () => ValidationMessage;
|
|
4
|
+
email: () => ValidationMessage;
|
|
5
|
+
required: () => ValidationMessage;
|
|
6
|
+
lettersOnly: (whiteSpaces: boolean) => ValidationMessage;
|
|
7
|
+
allowedOnly: (allowed: string) => ValidationMessage;
|
|
8
|
+
sameAs: (value: string) => ValidationMessage;
|
|
9
|
+
notSameAs: (value: string) => ValidationMessage;
|
|
10
|
+
boolean: {
|
|
11
|
+
base: () => ValidationMessage;
|
|
12
|
+
expected: (value: string) => ValidationMessage;
|
|
13
|
+
};
|
|
14
|
+
finite: {
|
|
15
|
+
base: () => ValidationMessage;
|
|
16
|
+
min: (value: number) => ValidationMessage;
|
|
17
|
+
max: (value: number) => ValidationMessage;
|
|
18
|
+
maxDigitsAfterDot: (value: number) => ValidationMessage;
|
|
19
|
+
};
|
|
20
|
+
number: {
|
|
21
|
+
base: () => ValidationMessage;
|
|
22
|
+
min: (value: number) => ValidationMessage;
|
|
23
|
+
max: (value: number) => ValidationMessage;
|
|
24
|
+
};
|
|
25
|
+
string: {
|
|
26
|
+
base: () => ValidationMessage;
|
|
27
|
+
min: (value: number) => ValidationMessage;
|
|
28
|
+
max: (value: number) => ValidationMessage;
|
|
29
|
+
};
|
|
30
|
+
array: {
|
|
31
|
+
base: () => ValidationMessage;
|
|
32
|
+
min: (value: number) => ValidationMessage;
|
|
33
|
+
max: (value: number) => ValidationMessage;
|
|
34
|
+
};
|
|
35
|
+
password: {
|
|
36
|
+
length: (value: number) => ValidationMessage;
|
|
37
|
+
specialChars: (value: number) => ValidationMessage;
|
|
38
|
+
lowerUpperCasePattern: () => ValidationMessage;
|
|
39
|
+
numbers: (value: number) => ValidationMessage;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RequestContext } from '../../../edges/context/index.js';
|
|
2
2
|
import { error, fail, redirect } from '@sveltejs/kit';
|
|
3
3
|
type Deps = {
|
|
4
|
-
context: Required<ReturnType<typeof RequestContext.current
|
|
4
|
+
context: Required<ReturnType<typeof RequestContext.current>['event']>;
|
|
5
5
|
utils: {
|
|
6
6
|
fail: typeof fail;
|
|
7
7
|
redirect: typeof redirect;
|