@palmares/schemas 0.0.1 → 0.1.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/.turbo/turbo-build$colon$watch.log +12 -410
- package/CHANGELOG.md +17 -0
- package/__tests__/.drizzle/migrations/0000_skinny_harrier.sql +22 -0
- package/__tests__/.drizzle/migrations/meta/0000_snapshot.json +156 -0
- package/__tests__/.drizzle/migrations/meta/_journal.json +13 -0
- package/__tests__/.drizzle/schema.ts +35 -0
- package/__tests__/drizzle.config.ts +11 -0
- package/__tests__/eslint.config.js +10 -0
- package/__tests__/manage.ts +5 -0
- package/__tests__/node_modules/.bin/drizzle-kit +17 -0
- package/__tests__/node_modules/.bin/esbuild +14 -0
- package/__tests__/node_modules/.bin/tsc +17 -0
- package/__tests__/node_modules/.bin/tsserver +17 -0
- package/__tests__/node_modules/.bin/tsx +17 -0
- package/__tests__/package.json +36 -0
- package/__tests__/sqlite.db +0 -0
- package/__tests__/src/core/array.test.ts +130 -0
- package/__tests__/src/core/boolean.test.ts +66 -0
- package/__tests__/src/core/datetime.test.ts +102 -0
- package/__tests__/src/core/index.ts +35 -0
- package/__tests__/src/core/model.test.ts +260 -0
- package/__tests__/src/core/models.ts +50 -0
- package/__tests__/src/core/numbers.test.ts +177 -0
- package/__tests__/src/core/object.test.ts +198 -0
- package/__tests__/src/core/string.test.ts +222 -0
- package/__tests__/src/core/test.test.ts +59 -0
- package/__tests__/src/core/types.test.ts +97 -0
- package/__tests__/src/core/union.test.ts +99 -0
- package/__tests__/src/settings.ts +71 -0
- package/__tests__/tsconfig.json +11 -0
- package/dist/cjs/src/adapter/fields/index.js +2 -2
- package/dist/cjs/src/adapter/fields/object.js +9 -0
- package/dist/cjs/src/adapter/index.js +1 -0
- package/dist/cjs/src/constants.js +1 -7
- package/dist/cjs/src/domain.js +146 -1
- package/dist/cjs/src/index.js +69 -74
- package/dist/cjs/src/model.js +206 -206
- package/dist/cjs/src/schema/array.js +185 -58
- package/dist/cjs/src/schema/boolean.js +105 -44
- package/dist/cjs/src/schema/datetime.js +104 -38
- package/dist/cjs/src/schema/number.js +134 -114
- package/dist/cjs/src/schema/object.js +106 -43
- package/dist/cjs/src/schema/schema.js +123 -75
- package/dist/cjs/src/schema/string.js +152 -58
- package/dist/cjs/src/schema/union.js +412 -290
- package/dist/cjs/src/utils.js +42 -15
- package/dist/cjs/src/validators/array.js +6 -1
- package/dist/cjs/src/validators/boolean.js +2 -0
- package/dist/cjs/src/validators/datetime.js +4 -0
- package/dist/cjs/src/validators/number.js +12 -40
- package/dist/cjs/src/validators/object.js +1 -0
- package/dist/cjs/src/validators/schema.js +5 -1
- package/dist/cjs/src/validators/string.js +30 -2
- package/dist/cjs/src/validators/union.js +5 -4
- package/dist/cjs/src/validators/utils.js +99 -27
- package/dist/cjs/tsconfig.types.tsbuildinfo +1 -1
- package/dist/cjs/types/adapter/fields/array.d.ts +2 -2
- package/dist/cjs/types/adapter/fields/array.d.ts.map +1 -1
- package/dist/cjs/types/adapter/fields/boolean.d.ts.map +1 -1
- package/dist/cjs/types/adapter/fields/datetime.d.ts.map +1 -1
- package/dist/cjs/types/adapter/fields/index.d.ts +2 -2
- package/dist/cjs/types/adapter/fields/index.d.ts.map +1 -1
- package/dist/cjs/types/adapter/fields/number.d.ts.map +1 -1
- package/dist/cjs/types/adapter/fields/object.d.ts +2 -1
- package/dist/cjs/types/adapter/fields/object.d.ts.map +1 -1
- package/dist/cjs/types/adapter/fields/string.d.ts.map +1 -1
- package/dist/cjs/types/adapter/fields/union.d.ts.map +1 -1
- package/dist/cjs/types/adapter/index.d.ts +1 -0
- package/dist/cjs/types/adapter/index.d.ts.map +1 -1
- package/dist/cjs/types/adapter/types.d.ts +28 -18
- package/dist/cjs/types/adapter/types.d.ts.map +1 -1
- package/dist/cjs/types/constants.d.ts +0 -1
- package/dist/cjs/types/constants.d.ts.map +1 -1
- package/dist/cjs/types/domain.d.ts +5 -4
- package/dist/cjs/types/domain.d.ts.map +1 -1
- package/dist/cjs/types/index.d.ts +78 -55
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/model.d.ts +17 -17
- package/dist/cjs/types/model.d.ts.map +1 -1
- package/dist/cjs/types/schema/array.d.ts +168 -47
- package/dist/cjs/types/schema/array.d.ts.map +1 -1
- package/dist/cjs/types/schema/boolean.d.ts +103 -44
- package/dist/cjs/types/schema/boolean.d.ts.map +1 -1
- package/dist/cjs/types/schema/datetime.d.ts +90 -30
- package/dist/cjs/types/schema/datetime.d.ts.map +1 -1
- package/dist/cjs/types/schema/number.d.ts +133 -125
- package/dist/cjs/types/schema/number.d.ts.map +1 -1
- package/dist/cjs/types/schema/object.d.ts +104 -35
- package/dist/cjs/types/schema/object.d.ts.map +1 -1
- package/dist/cjs/types/schema/schema.d.ts +62 -44
- package/dist/cjs/types/schema/schema.d.ts.map +1 -1
- package/dist/cjs/types/schema/string.d.ts +152 -65
- package/dist/cjs/types/schema/string.d.ts.map +1 -1
- package/dist/cjs/types/schema/types.d.ts +11 -2
- package/dist/cjs/types/schema/types.d.ts.map +1 -1
- package/dist/cjs/types/schema/union.d.ts +133 -40
- package/dist/cjs/types/schema/union.d.ts.map +1 -1
- package/dist/cjs/types/types.d.ts +35 -0
- package/dist/cjs/types/types.d.ts.map +1 -1
- package/dist/cjs/types/utils.d.ts +41 -27
- package/dist/cjs/types/utils.d.ts.map +1 -1
- package/dist/cjs/types/validators/array.d.ts.map +1 -1
- package/dist/cjs/types/validators/boolean.d.ts.map +1 -1
- package/dist/cjs/types/validators/datetime.d.ts.map +1 -1
- package/dist/cjs/types/validators/number.d.ts +5 -6
- package/dist/cjs/types/validators/number.d.ts.map +1 -1
- package/dist/cjs/types/validators/object.d.ts.map +1 -1
- package/dist/cjs/types/validators/schema.d.ts +2 -2
- package/dist/cjs/types/validators/schema.d.ts.map +1 -1
- package/dist/cjs/types/validators/string.d.ts +9 -9
- package/dist/cjs/types/validators/string.d.ts.map +1 -1
- package/dist/cjs/types/validators/utils.d.ts +44 -27
- package/dist/cjs/types/validators/utils.d.ts.map +1 -1
- package/dist/esm/src/adapter/fields/index.js +2 -2
- package/dist/esm/src/adapter/fields/object.js +6 -0
- package/dist/esm/src/adapter/index.js +1 -0
- package/dist/esm/src/constants.js +1 -2
- package/dist/esm/src/domain.js +11 -1
- package/dist/esm/src/index.js +38 -73
- package/dist/esm/src/model.js +83 -78
- package/dist/esm/src/schema/array.js +136 -54
- package/dist/esm/src/schema/boolean.js +98 -44
- package/dist/esm/src/schema/datetime.js +91 -38
- package/dist/esm/src/schema/number.js +127 -110
- package/dist/esm/src/schema/object.js +98 -43
- package/dist/esm/src/schema/schema.js +102 -67
- package/dist/esm/src/schema/string.js +147 -59
- package/dist/esm/src/schema/union.js +119 -40
- package/dist/esm/src/types.js +14 -1
- package/dist/esm/src/utils.js +56 -27
- package/dist/esm/src/validators/array.js +6 -1
- package/dist/esm/src/validators/boolean.js +2 -0
- package/dist/esm/src/validators/datetime.js +4 -0
- package/dist/esm/src/validators/number.js +9 -23
- package/dist/esm/src/validators/object.js +1 -0
- package/dist/esm/src/validators/schema.js +5 -1
- package/dist/esm/src/validators/string.js +30 -2
- package/dist/esm/src/validators/union.js +5 -4
- package/dist/esm/src/validators/utils.js +62 -36
- package/package.json +3 -3
- package/src/adapter/fields/array.ts +2 -2
- package/src/adapter/fields/boolean.ts +3 -8
- package/src/adapter/fields/datetime.ts +3 -9
- package/src/adapter/fields/index.ts +11 -11
- package/src/adapter/fields/number.ts +3 -9
- package/src/adapter/fields/object.ts +13 -10
- package/src/adapter/fields/string.ts +3 -9
- package/src/adapter/fields/union.ts +3 -9
- package/src/adapter/index.ts +1 -0
- package/src/adapter/types.ts +60 -45
- package/src/constants.ts +1 -3
- package/src/domain.ts +15 -1
- package/src/index.ts +189 -211
- package/src/model.ts +119 -115
- package/src/schema/array.ts +274 -90
- package/src/schema/boolean.ts +145 -60
- package/src/schema/datetime.ts +133 -49
- package/src/schema/number.ts +210 -173
- package/src/schema/object.ts +167 -74
- package/src/schema/schema.ts +205 -126
- package/src/schema/string.ts +221 -94
- package/src/schema/types.ts +44 -16
- package/src/schema/union.ts +193 -68
- package/src/types.ts +53 -0
- package/src/utils.ts +115 -57
- package/src/validators/array.ts +46 -27
- package/src/validators/boolean.ts +13 -7
- package/src/validators/datetime.ts +24 -16
- package/src/validators/number.ts +53 -63
- package/src/validators/object.ts +6 -5
- package/src/validators/schema.ts +33 -25
- package/src/validators/string.ts +122 -59
- package/src/validators/union.ts +8 -8
- package/src/validators/utils.ts +67 -42
package/src/validators/string.ts
CHANGED
@@ -1,11 +1,18 @@
|
|
1
|
+
import { type ValidationFallbackReturnType } from '../schema/types';
|
2
|
+
|
1
3
|
import type Schema from '../schema/schema';
|
2
4
|
import type StringSchema from '../schema/string';
|
3
|
-
import { type ValidationFallbackReturnType } from '../schema/types';
|
4
5
|
|
5
6
|
export function stringValidation(): ValidationFallbackReturnType {
|
6
7
|
return {
|
8
|
+
name: 'string',
|
7
9
|
type: 'medium',
|
8
|
-
|
10
|
+
// eslint-disable-next-line ts/require-await
|
11
|
+
callback: async (
|
12
|
+
value: any,
|
13
|
+
path: (string | number)[],
|
14
|
+
_options: Parameters<Schema['__transformToAdapter']>[0]
|
15
|
+
) => {
|
9
16
|
return {
|
10
17
|
parsed: value,
|
11
18
|
errors:
|
@@ -15,20 +22,27 @@ export function stringValidation(): ValidationFallbackReturnType {
|
|
15
22
|
{
|
16
23
|
isValid: typeof value === 'string',
|
17
24
|
code: 'string',
|
25
|
+
// eslint-disable-next-line ts/no-unnecessary-condition
|
18
26
|
path: path || [],
|
19
|
-
message: 'The value must be a string. Received: ' + typeof value
|
20
|
-
}
|
21
|
-
]
|
27
|
+
message: 'The value must be a string. Received: ' + typeof value
|
28
|
+
}
|
29
|
+
]
|
22
30
|
};
|
23
|
-
}
|
31
|
+
}
|
24
32
|
};
|
25
33
|
}
|
26
34
|
|
27
|
-
export function maxLength(args: StringSchema['__maxLength']): ValidationFallbackReturnType {
|
35
|
+
export function maxLength(args: NonNullable<StringSchema['__maxLength']>): ValidationFallbackReturnType {
|
28
36
|
return {
|
37
|
+
name: 'maxLength',
|
29
38
|
type: 'low',
|
30
|
-
|
31
|
-
|
39
|
+
// eslint-disable-next-line ts/require-await
|
40
|
+
callback: async (
|
41
|
+
value: any,
|
42
|
+
path: (string | number)[],
|
43
|
+
_options: Parameters<Schema['__transformToAdapter']>[0]
|
44
|
+
) => {
|
45
|
+
const isValid = value.length <= args.value;
|
32
46
|
|
33
47
|
return {
|
34
48
|
parsed: value,
|
@@ -38,20 +52,27 @@ export function maxLength(args: StringSchema['__maxLength']): ValidationFallback
|
|
38
52
|
{
|
39
53
|
isValid: false,
|
40
54
|
code: 'maxLength',
|
55
|
+
// eslint-disable-next-line ts/no-unnecessary-condition
|
41
56
|
path: path || [],
|
42
|
-
message: args.message
|
43
|
-
}
|
44
|
-
]
|
57
|
+
message: args.message
|
58
|
+
}
|
59
|
+
]
|
45
60
|
};
|
46
|
-
}
|
61
|
+
}
|
47
62
|
};
|
48
63
|
}
|
49
64
|
|
50
|
-
export function minLength(args: StringSchema['__maxLength']): ValidationFallbackReturnType {
|
65
|
+
export function minLength(args: NonNullable<StringSchema['__maxLength']>): ValidationFallbackReturnType {
|
51
66
|
return {
|
67
|
+
name: 'minLength',
|
52
68
|
type: 'low',
|
53
|
-
|
54
|
-
|
69
|
+
// eslint-disable-next-line ts/require-await
|
70
|
+
callback: async (
|
71
|
+
value: any,
|
72
|
+
path: (string | number)[],
|
73
|
+
_options: Parameters<Schema['__transformToAdapter']>[0]
|
74
|
+
) => {
|
75
|
+
const isValid = value.length >= args.value;
|
55
76
|
|
56
77
|
return {
|
57
78
|
parsed: value,
|
@@ -61,19 +82,26 @@ export function minLength(args: StringSchema['__maxLength']): ValidationFallback
|
|
61
82
|
{
|
62
83
|
isValid: false,
|
63
84
|
code: 'minLength',
|
85
|
+
// eslint-disable-next-line ts/no-unnecessary-condition
|
64
86
|
path: path || [],
|
65
|
-
message: args.message
|
66
|
-
}
|
67
|
-
]
|
87
|
+
message: args.message
|
88
|
+
}
|
89
|
+
]
|
68
90
|
};
|
69
|
-
}
|
91
|
+
}
|
70
92
|
};
|
71
93
|
}
|
72
94
|
|
73
|
-
export function endsWith(args: StringSchema['__endsWith']): ValidationFallbackReturnType {
|
95
|
+
export function endsWith(args: NonNullable<StringSchema['__endsWith']>): ValidationFallbackReturnType {
|
74
96
|
return {
|
97
|
+
name: 'endsWith',
|
75
98
|
type: 'low',
|
76
|
-
|
99
|
+
// eslint-disable-next-line ts/require-await
|
100
|
+
callback: async (
|
101
|
+
value: any,
|
102
|
+
path: (string | number)[],
|
103
|
+
_options: Parameters<Schema['__transformToAdapter']>[0]
|
104
|
+
) => {
|
77
105
|
const isValid = value.endsWith(args.value);
|
78
106
|
|
79
107
|
return {
|
@@ -84,19 +112,26 @@ export function endsWith(args: StringSchema['__endsWith']): ValidationFallbackRe
|
|
84
112
|
{
|
85
113
|
isValid: false,
|
86
114
|
code: 'endsWith',
|
115
|
+
// eslint-disable-next-line ts/no-unnecessary-condition
|
87
116
|
path: path || [],
|
88
|
-
message: args.message
|
89
|
-
}
|
90
|
-
]
|
117
|
+
message: args.message
|
118
|
+
}
|
119
|
+
]
|
91
120
|
};
|
92
|
-
}
|
121
|
+
}
|
93
122
|
};
|
94
123
|
}
|
95
124
|
|
96
|
-
export function startsWith(args: StringSchema['__startsWith']): ValidationFallbackReturnType {
|
125
|
+
export function startsWith(args: NonNullable<StringSchema['__startsWith']>): ValidationFallbackReturnType {
|
97
126
|
return {
|
127
|
+
name: 'startsWith',
|
98
128
|
type: 'low',
|
99
|
-
|
129
|
+
// eslint-disable-next-line ts/require-await
|
130
|
+
callback: async (
|
131
|
+
value: any,
|
132
|
+
path: (string | number)[],
|
133
|
+
_options: Parameters<Schema['__transformToAdapter']>[0]
|
134
|
+
) => {
|
100
135
|
const isValid = value.startsWith(args.value);
|
101
136
|
|
102
137
|
return {
|
@@ -107,19 +142,26 @@ export function startsWith(args: StringSchema['__startsWith']): ValidationFallba
|
|
107
142
|
{
|
108
143
|
isValid: false,
|
109
144
|
code: 'startsWith',
|
145
|
+
// eslint-disable-next-line ts/no-unnecessary-condition
|
110
146
|
path: path || [],
|
111
|
-
message: args.message
|
112
|
-
}
|
113
|
-
]
|
147
|
+
message: args.message
|
148
|
+
}
|
149
|
+
]
|
114
150
|
};
|
115
|
-
}
|
151
|
+
}
|
116
152
|
};
|
117
153
|
}
|
118
154
|
|
119
|
-
export function includes(args: StringSchema['__includes']): ValidationFallbackReturnType {
|
155
|
+
export function includes(args: NonNullable<StringSchema['__includes']>): ValidationFallbackReturnType {
|
120
156
|
return {
|
157
|
+
name: 'includes',
|
121
158
|
type: 'low',
|
122
|
-
|
159
|
+
// eslint-disable-next-line ts/require-await
|
160
|
+
callback: async (
|
161
|
+
value: any,
|
162
|
+
path: (string | number)[],
|
163
|
+
_options: Parameters<Schema['__transformToAdapter']>[0]
|
164
|
+
) => {
|
123
165
|
const isValid = value.includes(args.value);
|
124
166
|
|
125
167
|
return {
|
@@ -130,19 +172,26 @@ export function includes(args: StringSchema['__includes']): ValidationFallbackRe
|
|
130
172
|
{
|
131
173
|
isValid: false,
|
132
174
|
code: 'includes',
|
175
|
+
// eslint-disable-next-line ts/no-unnecessary-condition
|
133
176
|
path: path || [],
|
134
|
-
message: args.message
|
135
|
-
}
|
136
|
-
]
|
177
|
+
message: args.message
|
178
|
+
}
|
179
|
+
]
|
137
180
|
};
|
138
|
-
}
|
181
|
+
}
|
139
182
|
};
|
140
183
|
}
|
141
184
|
|
142
|
-
export function regex(args: StringSchema['__regex']): ValidationFallbackReturnType {
|
185
|
+
export function regex(args: NonNullable<StringSchema['__regex']>): ValidationFallbackReturnType {
|
143
186
|
return {
|
187
|
+
name: 'regex',
|
144
188
|
type: 'low',
|
145
|
-
|
189
|
+
// eslint-disable-next-line ts/require-await
|
190
|
+
callback: async (
|
191
|
+
value: any,
|
192
|
+
path: (string | number)[],
|
193
|
+
_options: Parameters<Schema['__transformToAdapter']>[0]
|
194
|
+
) => {
|
146
195
|
const isValid = args.value.test(value);
|
147
196
|
|
148
197
|
return {
|
@@ -153,23 +202,29 @@ export function regex(args: StringSchema['__regex']): ValidationFallbackReturnTy
|
|
153
202
|
{
|
154
203
|
isValid: false,
|
155
204
|
code: 'regex',
|
205
|
+
// eslint-disable-next-line ts/no-unnecessary-condition
|
156
206
|
path: path || [],
|
157
|
-
message: args.message
|
158
|
-
}
|
159
|
-
]
|
207
|
+
message: args.message
|
208
|
+
}
|
209
|
+
]
|
160
210
|
};
|
161
|
-
}
|
211
|
+
}
|
162
212
|
};
|
163
213
|
}
|
164
214
|
|
165
|
-
export function uuid(args: StringSchema['__uuid']): ValidationFallbackReturnType {
|
215
|
+
export function uuid(args: NonNullable<StringSchema['__uuid']>): ValidationFallbackReturnType {
|
166
216
|
// const uuidRegex =
|
167
217
|
// /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i;
|
168
|
-
const uuidRegex =
|
169
|
-
/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i;
|
218
|
+
const uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i;
|
170
219
|
return {
|
220
|
+
name: 'uuid',
|
171
221
|
type: 'low',
|
172
|
-
|
222
|
+
// eslint-disable-next-line ts/require-await
|
223
|
+
callback: async (
|
224
|
+
value: any,
|
225
|
+
path: (string | number)[],
|
226
|
+
_options: Parameters<Schema['__transformToAdapter']>[0]
|
227
|
+
) => {
|
173
228
|
const isValid = uuidRegex.test(value);
|
174
229
|
|
175
230
|
return {
|
@@ -180,20 +235,28 @@ export function uuid(args: StringSchema['__uuid']): ValidationFallbackReturnType
|
|
180
235
|
{
|
181
236
|
isValid: false,
|
182
237
|
code: 'uuid',
|
238
|
+
// eslint-disable-next-line ts/no-unnecessary-condition
|
183
239
|
path: path || [],
|
184
|
-
message: args.message
|
185
|
-
}
|
186
|
-
]
|
240
|
+
message: args.message
|
241
|
+
}
|
242
|
+
]
|
187
243
|
};
|
188
244
|
}
|
189
|
-
}
|
245
|
+
};
|
190
246
|
}
|
191
247
|
|
192
|
-
export function email(args: StringSchema['__email']): ValidationFallbackReturnType {
|
248
|
+
export function email(args: NonNullable<StringSchema['__email']>): ValidationFallbackReturnType {
|
193
249
|
const emailRegex = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i;
|
250
|
+
console.log('aquiiiiii');
|
194
251
|
return {
|
252
|
+
name: 'email',
|
195
253
|
type: 'low',
|
196
|
-
|
254
|
+
// eslint-disable-next-line ts/require-await
|
255
|
+
callback: async (
|
256
|
+
value: any,
|
257
|
+
path: (string | number)[],
|
258
|
+
_options: Parameters<Schema['__transformToAdapter']>[0]
|
259
|
+
) => {
|
197
260
|
const isValid = emailRegex.test(value);
|
198
261
|
|
199
262
|
return {
|
@@ -204,12 +267,12 @@ export function email(args: StringSchema['__email']): ValidationFallbackReturnTy
|
|
204
267
|
{
|
205
268
|
isValid: false,
|
206
269
|
code: 'email',
|
270
|
+
// eslint-disable-next-line ts/no-unnecessary-condition
|
207
271
|
path: path || [],
|
208
|
-
message: args.message
|
209
|
-
}
|
210
|
-
]
|
272
|
+
message: args.message
|
273
|
+
}
|
274
|
+
]
|
211
275
|
};
|
212
276
|
}
|
213
|
-
}
|
277
|
+
};
|
214
278
|
}
|
215
|
-
|
package/src/validators/union.ts
CHANGED
@@ -5,11 +5,12 @@ export function unionValidation(
|
|
5
5
|
schemas: readonly [Schema<any, any>, Schema<any, any>, ...Schema<any, any>[]]
|
6
6
|
): ValidationFallbackReturnType {
|
7
7
|
return {
|
8
|
-
|
8
|
+
name: 'union',
|
9
|
+
type: 'medium',
|
9
10
|
callback: async (value, path, options) => {
|
10
11
|
const parsedValues: Awaited<ReturnType<Schema['__parse']>> = {
|
11
12
|
parsed: value,
|
12
|
-
errors: []
|
13
|
+
errors: []
|
13
14
|
};
|
14
15
|
const startingToInternalBubbleUpLength = options.toInternalToBubbleUp?.length || 0;
|
15
16
|
|
@@ -31,22 +32,21 @@ export function unionValidation(
|
|
31
32
|
if (hasNoErrorsSoItsAValidSchemaAndShouldResetOldErrors) {
|
32
33
|
return {
|
33
34
|
parsed: parsedValues.parsed,
|
34
|
-
errors: []
|
35
|
+
errors: []
|
35
36
|
};
|
36
37
|
} else if (startingToInternalBubbleUpLength < (options.toInternalToBubbleUp?.length || 0)) {
|
37
|
-
// If there is a new toInternalToBubbleUp we should remove the ones that we added since this is not a
|
38
|
-
// we shouldn't be calling the `toInternal` on that schemas.
|
38
|
+
// If there is a new toInternalToBubbleUp we should remove the ones that we added since this is not a
|
39
|
+
// valid schema, we shouldn't be calling the `toInternal` on that schemas.
|
39
40
|
const numberOfElementsToRemove =
|
40
41
|
(options.toInternalToBubbleUp?.length || 0) - startingToInternalBubbleUpLength;
|
41
42
|
options.toInternalToBubbleUp?.splice(startingToInternalBubbleUpLength, numberOfElementsToRemove);
|
42
43
|
}
|
43
44
|
}
|
44
|
-
|
45
45
|
return {
|
46
46
|
parsed: parsedValues.parsed,
|
47
47
|
// eslint-disable-next-line ts/no-unnecessary-condition
|
48
|
-
errors: parsedValues.errors ? parsedValues.errors : []
|
48
|
+
errors: Array.isArray(parsedValues.errors) ? parsedValues.errors : []
|
49
49
|
};
|
50
|
-
}
|
50
|
+
}
|
51
51
|
};
|
52
52
|
}
|
package/src/validators/utils.ts
CHANGED
@@ -4,13 +4,13 @@ import type Schema from '../schema/schema';
|
|
4
4
|
import type {
|
5
5
|
ValidationFallbackCallbackReturnType,
|
6
6
|
ValidationFallbackCallbackType,
|
7
|
-
ValidationFallbackReturnType
|
7
|
+
ValidationFallbackReturnType
|
8
8
|
} from '../schema/types';
|
9
9
|
|
10
10
|
const priorityByType = {
|
11
11
|
low: 0,
|
12
12
|
medium: 1,
|
13
|
-
high: 2
|
13
|
+
high: 2
|
14
14
|
};
|
15
15
|
|
16
16
|
const typeByPriority = Object.entries(priorityByType).reduce(
|
@@ -22,24 +22,30 @@ const typeByPriority = Object.entries(priorityByType).reduce(
|
|
22
22
|
);
|
23
23
|
|
24
24
|
/**
|
25
|
-
* Okay, so what is this? This is a validator class, it represents a Node on a linked list. The linked list
|
26
|
-
* priority validators on the
|
25
|
+
* Okay, so what is this? This is a validator class, it represents a Node on a linked list. The linked list
|
26
|
+
* has lower priority validators on the end of the list and higher priority validators on the start of the
|
27
|
+
* list. Maybe in the future we can change that to a binary tree, but for now this is enough.
|
27
28
|
*
|
28
|
-
* Why did we choose this approach? Because what i was doing was that i saw myself repeating the same code 3
|
29
|
-
*
|
30
|
-
*
|
31
|
-
*
|
29
|
+
* Why did we choose this approach? Because what i was doing was that i saw myself repeating the same code 3
|
30
|
+
* times on the schema in order to make the validation work. Each validator had a different return type, i
|
31
|
+
* didn't like that. I wanted to add more power and control on the validator, not on the schema. So i created
|
32
|
+
* this class. So pretty much, over here and on each validator we can define the type it is. It can actually
|
33
|
+
* be three: `low`, `medium` and `high`. The `low` validators are the ones that are going to be executed last,
|
34
|
+
* The `high` validators are the ones that are going to be executed first. High validators validate if the value
|
35
|
+
* is null or undefined, if it allows that. It can stop the execution of the other validators if it wants to.
|
32
36
|
*
|
33
|
-
* Example: Let's say that the value is null, if the value is null, is there a reason to check if it's a number?
|
34
|
-
*
|
35
|
-
* the
|
37
|
+
* Example: Let's say that the value is null, if the value is null, is there a reason to check if it's a number?
|
38
|
+
* No, right? So the high validator can stop the execution of the other validators.
|
39
|
+
* Same as before, if the value is not a number, is there a reason to check if it's value is greater than the
|
40
|
+
* `max` allowed 10? No, right? So the medium validator can stop the execution of the other validators.
|
36
41
|
*
|
37
|
-
* That's what this solve, it's a better approach than repeating the same code 3 times on the schema. It's also
|
38
|
-
* without changing the schema.
|
42
|
+
* That's what this solve, it's a better approach than repeating the same code 3 times on the schema. It's also
|
43
|
+
* more powerful, because if we need to add any extra priorities we can do that easily without changing the schema.
|
39
44
|
*/
|
40
45
|
export default class Validator {
|
41
46
|
child?: Validator;
|
42
47
|
parent?: Validator;
|
48
|
+
fallbackNamesAdded = new Set();
|
43
49
|
priority: number;
|
44
50
|
fallbacks: ((
|
45
51
|
value: any,
|
@@ -57,19 +63,27 @@ export default class Validator {
|
|
57
63
|
}>)[] = [];
|
58
64
|
|
59
65
|
constructor(type: ValidatorTypes) {
|
66
|
+
this.fallbackNamesAdded = new Set();
|
67
|
+
this.fallbacks = [];
|
60
68
|
this.priority = priorityByType[type];
|
61
69
|
}
|
62
70
|
|
63
71
|
/**
|
64
|
-
* We create all of the validators on the schema in order, i actually didn't want to go on that route but i
|
72
|
+
* We create all of the validators on the schema in order, i actually didn't want to go on that route but i
|
73
|
+
* found it easier to do so.
|
65
74
|
*
|
66
|
-
* The logic here is simple, if it's not the same priority we will walk on the linked list until we find
|
67
|
-
*
|
68
|
-
*
|
75
|
+
* The logic here is simple, if it's not the same priority we will walk on the linked list until we find
|
76
|
+
* a validator that matches the priority we are expecting. If we can't walk anymore, we create the next
|
77
|
+
* priority validator and append it to the linked list. Be aware that it's a double linked list, so we
|
78
|
+
* can walk both ways, from the end to the start and from the start to the end.
|
79
|
+
* So you don't really need to start from the root, the linked list can start from anywhere and it will
|
80
|
+
* find it's way through.
|
69
81
|
*
|
70
|
-
* I know there are better ways to do this instead of walking through the linked list, but like i explained
|
82
|
+
* I know there are better ways to do this instead of walking through the linked list, but like i explained
|
83
|
+
* before, this is enough for now.
|
71
84
|
*
|
72
|
-
* If the priority is higher than the current priority saved on the schema, we should substitute the
|
85
|
+
* If the priority is higher than the current priority saved on the schema, we should substitute the
|
86
|
+
* rootValidator on the schema with the new one.
|
73
87
|
*
|
74
88
|
* @param schema - The schema that we are working on right now, all fallbacks are tied to that specific schema.
|
75
89
|
* @param type - The type of the fallback that we are adding.
|
@@ -80,14 +94,15 @@ export default class Validator {
|
|
80
94
|
private checkAppendOrCreate(
|
81
95
|
schema: Schema,
|
82
96
|
type: ValidatorTypes,
|
97
|
+
fallbackName: string,
|
83
98
|
fallback: ValidationFallbackCallbackType,
|
84
99
|
childOrParent: 'child' | 'parent',
|
85
100
|
options?: Parameters<(typeof Validator)['createAndAppendFallback']>[2]
|
86
101
|
) {
|
87
|
-
|
88
102
|
const schemaWithProtected = schema as Schema & { __rootFallbacksValidator?: Schema['__rootFallbacksValidator'] };
|
89
103
|
|
90
|
-
if (this[childOrParent])
|
104
|
+
if (this[childOrParent])
|
105
|
+
(this as any)[childOrParent].addFallback(schemaWithProtected, type, fallbackName, fallback, options);
|
91
106
|
else {
|
92
107
|
const nextPriority = childOrParent === 'child' ? this.priority - 1 : this.priority + 1;
|
93
108
|
if (Object.keys(typeByPriority).includes(String(nextPriority))) {
|
@@ -96,7 +111,7 @@ export default class Validator {
|
|
96
111
|
const validatorInstance = new Validator(nextType);
|
97
112
|
this[childOrParent] = validatorInstance;
|
98
113
|
(this as any)[childOrParent][childOrParent === 'parent' ? 'child' : 'parent'] = this;
|
99
|
-
(this as any)[childOrParent].addFallback(schemaWithProtected, type, fallback, options);
|
114
|
+
(this as any)[childOrParent].addFallback(schemaWithProtected, type, fallbackName, fallback, options);
|
100
115
|
if (nextPriority > schemaWithProtected.__rootFallbacksValidator.priority)
|
101
116
|
schemaWithProtected.__rootFallbacksValidator = validatorInstance;
|
102
117
|
}
|
@@ -106,23 +121,29 @@ export default class Validator {
|
|
106
121
|
addFallback(
|
107
122
|
schema: Schema,
|
108
123
|
type: ValidatorTypes,
|
124
|
+
fallbackName: string,
|
109
125
|
fallback: ValidationFallbackCallbackType,
|
110
126
|
options?: Parameters<(typeof Validator)['createAndAppendFallback']>[2]
|
111
127
|
) {
|
128
|
+
if (this.fallbackNamesAdded.has(fallbackName) && options?.removeCurrent !== true) return;
|
129
|
+
this.fallbackNamesAdded.add(fallbackName);
|
112
130
|
const priority = priorityByType[type];
|
113
131
|
if (this.priority === priority) {
|
114
132
|
if (typeof options?.at === 'number')
|
115
133
|
this.fallbacks.splice(options.at, options.removeCurrent === true ? 1 : 0, fallback);
|
116
134
|
else this.fallbacks.push(fallback);
|
117
|
-
} else if (priority > this.priority)
|
118
|
-
|
135
|
+
} else if (priority > this.priority)
|
136
|
+
this.checkAppendOrCreate(schema, type, fallbackName, fallback, 'parent', options);
|
137
|
+
else if (priority < this.priority) this.checkAppendOrCreate(schema, type, fallbackName, fallback, 'child', options);
|
119
138
|
}
|
120
139
|
|
121
140
|
/**
|
122
|
-
* Validates the value against all of the fallbacks, the fallbacks are executed in order, from the highest
|
123
|
-
* A validator can stop the execution of the other validators if it feels
|
141
|
+
* Validates the value against all of the fallbacks, the fallbacks are executed in order, from the highest
|
142
|
+
* priority to the lowest priority. A validator can stop the execution of the other validators if it feels
|
143
|
+
* like so. Like on the example of a value being null or undefined.
|
124
144
|
*
|
125
|
-
* @param errorsAsHashedSet - This is a set that contains all of the errors that we already found, this is
|
145
|
+
* @param errorsAsHashedSet - This is a set that contains all of the errors that we already found, this is
|
146
|
+
* used to avoid duplicated errors.
|
126
147
|
* @param path - The path that we are validating right now.
|
127
148
|
* @param parseResult - The result of the parsing, it contains the parsed value and the errors that we found.
|
128
149
|
* @param options - The options that we are passing to the fallback.
|
@@ -143,34 +164,38 @@ export default class Validator {
|
|
143
164
|
parseResult.parsed = parsed;
|
144
165
|
for (const error of errors) {
|
145
166
|
if (error.isValid === false) {
|
146
|
-
const
|
167
|
+
const sortedError = Object.fromEntries(Object.entries(error).sort(([a], [b]) => a.localeCompare(b)));
|
168
|
+
|
169
|
+
const hashedError = JSON.stringify(sortedError);
|
147
170
|
if (errorsAsHashedSet.has(hashedError)) continue;
|
171
|
+
errorsAsHashedSet.add(hashedError);
|
148
172
|
if (!Array.isArray(parseResult.errors)) parseResult.errors = [];
|
149
|
-
parseResult.errors.push(
|
173
|
+
parseResult.errors.push({
|
174
|
+
...error,
|
175
|
+
received: parseResult.parsed
|
176
|
+
});
|
150
177
|
}
|
151
178
|
}
|
152
179
|
doesItShouldPreventChildValidation = doesItShouldPreventChildValidation || preventChildValidation || false;
|
153
180
|
}
|
154
181
|
|
155
182
|
if (this.child && doesItShouldPreventChildValidation === false)
|
156
|
-
return this.child.validate(
|
157
|
-
errorsAsHashedSet,
|
158
|
-
path,
|
159
|
-
parseResult,
|
160
|
-
options
|
161
|
-
);
|
183
|
+
return await this.child.validate(errorsAsHashedSet, path, parseResult, options);
|
162
184
|
|
163
185
|
return parseResult as unknown as Promise<ValidationFallbackCallbackReturnType>;
|
164
186
|
}
|
165
187
|
|
166
188
|
/**
|
167
|
-
* This static method takes care of everything for you. This means that you should only call this method
|
168
|
-
*
|
189
|
+
* This static method takes care of everything for you. This means that you should only call this method
|
190
|
+
* for appending new fallbacks, it takes care of creating the root validator and making sure that the
|
191
|
+
* rootValidator on the schema is the highest priority one.
|
169
192
|
*
|
170
|
-
* @param schema - The schema that we are working on right now, all fallbacks are tied to that specific
|
171
|
-
* so you don't need to worry about that.
|
172
|
-
* @param fallback - The fallback that we are adding. This is an object that contains the type of the
|
173
|
-
*
|
193
|
+
* @param schema - The schema that we are working on right now, all fallbacks are tied to that specific
|
194
|
+
* schema. We automatically define the rootValidator on the schema so you don't need to worry about that.
|
195
|
+
* @param fallback - The fallback that we are adding. This is an object that contains the type of the
|
196
|
+
* fallback and the callback that we are adding.
|
197
|
+
* @param options - The options that we are passing to the fallback. Options like `at` and `removeCurrent`
|
198
|
+
* are passed to the `addFallback` method.
|
174
199
|
*/
|
175
200
|
static createAndAppendFallback(
|
176
201
|
schema: Schema<any, any>,
|
@@ -188,7 +213,7 @@ export default class Validator {
|
|
188
213
|
validatorInstance = new Validator(fallback.type);
|
189
214
|
schemaWithProtected.__rootFallbacksValidator = validatorInstance;
|
190
215
|
}
|
191
|
-
validatorInstance.addFallback(schema, fallback.type, fallback.callback, options);
|
216
|
+
validatorInstance.addFallback(schema, fallback.type, fallback.name, fallback.callback, options);
|
192
217
|
return validatorInstance;
|
193
218
|
}
|
194
219
|
|