@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.
Files changed (174) hide show
  1. package/.turbo/turbo-build$colon$watch.log +12 -410
  2. package/CHANGELOG.md +17 -0
  3. package/__tests__/.drizzle/migrations/0000_skinny_harrier.sql +22 -0
  4. package/__tests__/.drizzle/migrations/meta/0000_snapshot.json +156 -0
  5. package/__tests__/.drizzle/migrations/meta/_journal.json +13 -0
  6. package/__tests__/.drizzle/schema.ts +35 -0
  7. package/__tests__/drizzle.config.ts +11 -0
  8. package/__tests__/eslint.config.js +10 -0
  9. package/__tests__/manage.ts +5 -0
  10. package/__tests__/node_modules/.bin/drizzle-kit +17 -0
  11. package/__tests__/node_modules/.bin/esbuild +14 -0
  12. package/__tests__/node_modules/.bin/tsc +17 -0
  13. package/__tests__/node_modules/.bin/tsserver +17 -0
  14. package/__tests__/node_modules/.bin/tsx +17 -0
  15. package/__tests__/package.json +36 -0
  16. package/__tests__/sqlite.db +0 -0
  17. package/__tests__/src/core/array.test.ts +130 -0
  18. package/__tests__/src/core/boolean.test.ts +66 -0
  19. package/__tests__/src/core/datetime.test.ts +102 -0
  20. package/__tests__/src/core/index.ts +35 -0
  21. package/__tests__/src/core/model.test.ts +260 -0
  22. package/__tests__/src/core/models.ts +50 -0
  23. package/__tests__/src/core/numbers.test.ts +177 -0
  24. package/__tests__/src/core/object.test.ts +198 -0
  25. package/__tests__/src/core/string.test.ts +222 -0
  26. package/__tests__/src/core/test.test.ts +59 -0
  27. package/__tests__/src/core/types.test.ts +97 -0
  28. package/__tests__/src/core/union.test.ts +99 -0
  29. package/__tests__/src/settings.ts +71 -0
  30. package/__tests__/tsconfig.json +11 -0
  31. package/dist/cjs/src/adapter/fields/index.js +2 -2
  32. package/dist/cjs/src/adapter/fields/object.js +9 -0
  33. package/dist/cjs/src/adapter/index.js +1 -0
  34. package/dist/cjs/src/constants.js +1 -7
  35. package/dist/cjs/src/domain.js +146 -1
  36. package/dist/cjs/src/index.js +69 -74
  37. package/dist/cjs/src/model.js +206 -206
  38. package/dist/cjs/src/schema/array.js +185 -58
  39. package/dist/cjs/src/schema/boolean.js +105 -44
  40. package/dist/cjs/src/schema/datetime.js +104 -38
  41. package/dist/cjs/src/schema/number.js +134 -114
  42. package/dist/cjs/src/schema/object.js +106 -43
  43. package/dist/cjs/src/schema/schema.js +123 -75
  44. package/dist/cjs/src/schema/string.js +152 -58
  45. package/dist/cjs/src/schema/union.js +412 -290
  46. package/dist/cjs/src/utils.js +42 -15
  47. package/dist/cjs/src/validators/array.js +6 -1
  48. package/dist/cjs/src/validators/boolean.js +2 -0
  49. package/dist/cjs/src/validators/datetime.js +4 -0
  50. package/dist/cjs/src/validators/number.js +12 -40
  51. package/dist/cjs/src/validators/object.js +1 -0
  52. package/dist/cjs/src/validators/schema.js +5 -1
  53. package/dist/cjs/src/validators/string.js +30 -2
  54. package/dist/cjs/src/validators/union.js +5 -4
  55. package/dist/cjs/src/validators/utils.js +99 -27
  56. package/dist/cjs/tsconfig.types.tsbuildinfo +1 -1
  57. package/dist/cjs/types/adapter/fields/array.d.ts +2 -2
  58. package/dist/cjs/types/adapter/fields/array.d.ts.map +1 -1
  59. package/dist/cjs/types/adapter/fields/boolean.d.ts.map +1 -1
  60. package/dist/cjs/types/adapter/fields/datetime.d.ts.map +1 -1
  61. package/dist/cjs/types/adapter/fields/index.d.ts +2 -2
  62. package/dist/cjs/types/adapter/fields/index.d.ts.map +1 -1
  63. package/dist/cjs/types/adapter/fields/number.d.ts.map +1 -1
  64. package/dist/cjs/types/adapter/fields/object.d.ts +2 -1
  65. package/dist/cjs/types/adapter/fields/object.d.ts.map +1 -1
  66. package/dist/cjs/types/adapter/fields/string.d.ts.map +1 -1
  67. package/dist/cjs/types/adapter/fields/union.d.ts.map +1 -1
  68. package/dist/cjs/types/adapter/index.d.ts +1 -0
  69. package/dist/cjs/types/adapter/index.d.ts.map +1 -1
  70. package/dist/cjs/types/adapter/types.d.ts +28 -18
  71. package/dist/cjs/types/adapter/types.d.ts.map +1 -1
  72. package/dist/cjs/types/constants.d.ts +0 -1
  73. package/dist/cjs/types/constants.d.ts.map +1 -1
  74. package/dist/cjs/types/domain.d.ts +5 -4
  75. package/dist/cjs/types/domain.d.ts.map +1 -1
  76. package/dist/cjs/types/index.d.ts +78 -55
  77. package/dist/cjs/types/index.d.ts.map +1 -1
  78. package/dist/cjs/types/model.d.ts +17 -17
  79. package/dist/cjs/types/model.d.ts.map +1 -1
  80. package/dist/cjs/types/schema/array.d.ts +168 -47
  81. package/dist/cjs/types/schema/array.d.ts.map +1 -1
  82. package/dist/cjs/types/schema/boolean.d.ts +103 -44
  83. package/dist/cjs/types/schema/boolean.d.ts.map +1 -1
  84. package/dist/cjs/types/schema/datetime.d.ts +90 -30
  85. package/dist/cjs/types/schema/datetime.d.ts.map +1 -1
  86. package/dist/cjs/types/schema/number.d.ts +133 -125
  87. package/dist/cjs/types/schema/number.d.ts.map +1 -1
  88. package/dist/cjs/types/schema/object.d.ts +104 -35
  89. package/dist/cjs/types/schema/object.d.ts.map +1 -1
  90. package/dist/cjs/types/schema/schema.d.ts +62 -44
  91. package/dist/cjs/types/schema/schema.d.ts.map +1 -1
  92. package/dist/cjs/types/schema/string.d.ts +152 -65
  93. package/dist/cjs/types/schema/string.d.ts.map +1 -1
  94. package/dist/cjs/types/schema/types.d.ts +11 -2
  95. package/dist/cjs/types/schema/types.d.ts.map +1 -1
  96. package/dist/cjs/types/schema/union.d.ts +133 -40
  97. package/dist/cjs/types/schema/union.d.ts.map +1 -1
  98. package/dist/cjs/types/types.d.ts +35 -0
  99. package/dist/cjs/types/types.d.ts.map +1 -1
  100. package/dist/cjs/types/utils.d.ts +41 -27
  101. package/dist/cjs/types/utils.d.ts.map +1 -1
  102. package/dist/cjs/types/validators/array.d.ts.map +1 -1
  103. package/dist/cjs/types/validators/boolean.d.ts.map +1 -1
  104. package/dist/cjs/types/validators/datetime.d.ts.map +1 -1
  105. package/dist/cjs/types/validators/number.d.ts +5 -6
  106. package/dist/cjs/types/validators/number.d.ts.map +1 -1
  107. package/dist/cjs/types/validators/object.d.ts.map +1 -1
  108. package/dist/cjs/types/validators/schema.d.ts +2 -2
  109. package/dist/cjs/types/validators/schema.d.ts.map +1 -1
  110. package/dist/cjs/types/validators/string.d.ts +9 -9
  111. package/dist/cjs/types/validators/string.d.ts.map +1 -1
  112. package/dist/cjs/types/validators/utils.d.ts +44 -27
  113. package/dist/cjs/types/validators/utils.d.ts.map +1 -1
  114. package/dist/esm/src/adapter/fields/index.js +2 -2
  115. package/dist/esm/src/adapter/fields/object.js +6 -0
  116. package/dist/esm/src/adapter/index.js +1 -0
  117. package/dist/esm/src/constants.js +1 -2
  118. package/dist/esm/src/domain.js +11 -1
  119. package/dist/esm/src/index.js +38 -73
  120. package/dist/esm/src/model.js +83 -78
  121. package/dist/esm/src/schema/array.js +136 -54
  122. package/dist/esm/src/schema/boolean.js +98 -44
  123. package/dist/esm/src/schema/datetime.js +91 -38
  124. package/dist/esm/src/schema/number.js +127 -110
  125. package/dist/esm/src/schema/object.js +98 -43
  126. package/dist/esm/src/schema/schema.js +102 -67
  127. package/dist/esm/src/schema/string.js +147 -59
  128. package/dist/esm/src/schema/union.js +119 -40
  129. package/dist/esm/src/types.js +14 -1
  130. package/dist/esm/src/utils.js +56 -27
  131. package/dist/esm/src/validators/array.js +6 -1
  132. package/dist/esm/src/validators/boolean.js +2 -0
  133. package/dist/esm/src/validators/datetime.js +4 -0
  134. package/dist/esm/src/validators/number.js +9 -23
  135. package/dist/esm/src/validators/object.js +1 -0
  136. package/dist/esm/src/validators/schema.js +5 -1
  137. package/dist/esm/src/validators/string.js +30 -2
  138. package/dist/esm/src/validators/union.js +5 -4
  139. package/dist/esm/src/validators/utils.js +62 -36
  140. package/package.json +3 -3
  141. package/src/adapter/fields/array.ts +2 -2
  142. package/src/adapter/fields/boolean.ts +3 -8
  143. package/src/adapter/fields/datetime.ts +3 -9
  144. package/src/adapter/fields/index.ts +11 -11
  145. package/src/adapter/fields/number.ts +3 -9
  146. package/src/adapter/fields/object.ts +13 -10
  147. package/src/adapter/fields/string.ts +3 -9
  148. package/src/adapter/fields/union.ts +3 -9
  149. package/src/adapter/index.ts +1 -0
  150. package/src/adapter/types.ts +60 -45
  151. package/src/constants.ts +1 -3
  152. package/src/domain.ts +15 -1
  153. package/src/index.ts +189 -211
  154. package/src/model.ts +119 -115
  155. package/src/schema/array.ts +274 -90
  156. package/src/schema/boolean.ts +145 -60
  157. package/src/schema/datetime.ts +133 -49
  158. package/src/schema/number.ts +210 -173
  159. package/src/schema/object.ts +167 -74
  160. package/src/schema/schema.ts +205 -126
  161. package/src/schema/string.ts +221 -94
  162. package/src/schema/types.ts +44 -16
  163. package/src/schema/union.ts +193 -68
  164. package/src/types.ts +53 -0
  165. package/src/utils.ts +115 -57
  166. package/src/validators/array.ts +46 -27
  167. package/src/validators/boolean.ts +13 -7
  168. package/src/validators/datetime.ts +24 -16
  169. package/src/validators/number.ts +53 -63
  170. package/src/validators/object.ts +6 -5
  171. package/src/validators/schema.ts +33 -25
  172. package/src/validators/string.ts +122 -59
  173. package/src/validators/union.ts +8 -8
  174. package/src/validators/utils.ts +67 -42
@@ -1,5 +1,6 @@
1
1
  export function optional(args) {
2
2
  return {
3
+ name: 'optional',
3
4
  type: 'high',
4
5
  // eslint-disable-next-line ts/require-await
5
6
  callback: async (value, path)=>{
@@ -33,6 +34,7 @@ export function optional(args) {
33
34
  }
34
35
  export function nullable(args) {
35
36
  return {
37
+ name: 'nullable',
36
38
  type: 'high',
37
39
  // eslint-disable-next-line ts/require-await
38
40
  callback: async (value, path)=>{
@@ -48,7 +50,7 @@ export function nullable(args) {
48
50
  {
49
51
  isValid: false,
50
52
  message: args.message,
51
- code: 'cannot_be_null',
53
+ code: 'null',
52
54
  // eslint-disable-next-line ts/no-unnecessary-condition
53
55
  path: path || []
54
56
  }
@@ -66,6 +68,7 @@ export function nullable(args) {
66
68
  }
67
69
  export function checkType(args) {
68
70
  return {
71
+ name: 'checkType',
69
72
  type: 'medium',
70
73
  // eslint-disable-next-line ts/require-await
71
74
  callback: async (value, path)=>{
@@ -92,6 +95,7 @@ export function checkType(args) {
92
95
  }
93
96
  export function is(args) {
94
97
  return {
98
+ name: 'is',
95
99
  type: 'medium',
96
100
  // eslint-disable-next-line ts/require-await
97
101
  callback: async (value, path, _options)=>{
@@ -1,6 +1,8 @@
1
1
  export function stringValidation() {
2
2
  return {
3
+ name: 'string',
3
4
  type: 'medium',
5
+ // eslint-disable-next-line ts/require-await
4
6
  callback: async (value, path, _options)=>{
5
7
  return {
6
8
  parsed: value,
@@ -8,6 +10,7 @@ export function stringValidation() {
8
10
  {
9
11
  isValid: typeof value === 'string',
10
12
  code: 'string',
13
+ // eslint-disable-next-line ts/no-unnecessary-condition
11
14
  path: path || [],
12
15
  message: 'The value must be a string. Received: ' + typeof value
13
16
  }
@@ -18,15 +21,18 @@ export function stringValidation() {
18
21
  }
19
22
  export function maxLength(args) {
20
23
  return {
24
+ name: 'maxLength',
21
25
  type: 'low',
26
+ // eslint-disable-next-line ts/require-await
22
27
  callback: async (value, path, _options)=>{
23
- const isValid = args.inclusive ? value.length <= args.value : value.length < args.value;
28
+ const isValid = value.length <= args.value;
24
29
  return {
25
30
  parsed: value,
26
31
  errors: isValid ? [] : [
27
32
  {
28
33
  isValid: false,
29
34
  code: 'maxLength',
35
+ // eslint-disable-next-line ts/no-unnecessary-condition
30
36
  path: path || [],
31
37
  message: args.message
32
38
  }
@@ -37,15 +43,18 @@ export function maxLength(args) {
37
43
  }
38
44
  export function minLength(args) {
39
45
  return {
46
+ name: 'minLength',
40
47
  type: 'low',
48
+ // eslint-disable-next-line ts/require-await
41
49
  callback: async (value, path, _options)=>{
42
- const isValid = args.inclusive ? value.length >= args.value : value.length > args.value;
50
+ const isValid = value.length >= args.value;
43
51
  return {
44
52
  parsed: value,
45
53
  errors: isValid ? [] : [
46
54
  {
47
55
  isValid: false,
48
56
  code: 'minLength',
57
+ // eslint-disable-next-line ts/no-unnecessary-condition
49
58
  path: path || [],
50
59
  message: args.message
51
60
  }
@@ -56,7 +65,9 @@ export function minLength(args) {
56
65
  }
57
66
  export function endsWith(args) {
58
67
  return {
68
+ name: 'endsWith',
59
69
  type: 'low',
70
+ // eslint-disable-next-line ts/require-await
60
71
  callback: async (value, path, _options)=>{
61
72
  const isValid = value.endsWith(args.value);
62
73
  return {
@@ -65,6 +76,7 @@ export function endsWith(args) {
65
76
  {
66
77
  isValid: false,
67
78
  code: 'endsWith',
79
+ // eslint-disable-next-line ts/no-unnecessary-condition
68
80
  path: path || [],
69
81
  message: args.message
70
82
  }
@@ -75,7 +87,9 @@ export function endsWith(args) {
75
87
  }
76
88
  export function startsWith(args) {
77
89
  return {
90
+ name: 'startsWith',
78
91
  type: 'low',
92
+ // eslint-disable-next-line ts/require-await
79
93
  callback: async (value, path, _options)=>{
80
94
  const isValid = value.startsWith(args.value);
81
95
  return {
@@ -84,6 +98,7 @@ export function startsWith(args) {
84
98
  {
85
99
  isValid: false,
86
100
  code: 'startsWith',
101
+ // eslint-disable-next-line ts/no-unnecessary-condition
87
102
  path: path || [],
88
103
  message: args.message
89
104
  }
@@ -94,7 +109,9 @@ export function startsWith(args) {
94
109
  }
95
110
  export function includes(args) {
96
111
  return {
112
+ name: 'includes',
97
113
  type: 'low',
114
+ // eslint-disable-next-line ts/require-await
98
115
  callback: async (value, path, _options)=>{
99
116
  const isValid = value.includes(args.value);
100
117
  return {
@@ -103,6 +120,7 @@ export function includes(args) {
103
120
  {
104
121
  isValid: false,
105
122
  code: 'includes',
123
+ // eslint-disable-next-line ts/no-unnecessary-condition
106
124
  path: path || [],
107
125
  message: args.message
108
126
  }
@@ -113,7 +131,9 @@ export function includes(args) {
113
131
  }
114
132
  export function regex(args) {
115
133
  return {
134
+ name: 'regex',
116
135
  type: 'low',
136
+ // eslint-disable-next-line ts/require-await
117
137
  callback: async (value, path, _options)=>{
118
138
  const isValid = args.value.test(value);
119
139
  return {
@@ -122,6 +142,7 @@ export function regex(args) {
122
142
  {
123
143
  isValid: false,
124
144
  code: 'regex',
145
+ // eslint-disable-next-line ts/no-unnecessary-condition
125
146
  path: path || [],
126
147
  message: args.message
127
148
  }
@@ -135,7 +156,9 @@ export function uuid(args) {
135
156
  // /^([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;
136
157
  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;
137
158
  return {
159
+ name: 'uuid',
138
160
  type: 'low',
161
+ // eslint-disable-next-line ts/require-await
139
162
  callback: async (value, path, _options)=>{
140
163
  const isValid = uuidRegex.test(value);
141
164
  return {
@@ -144,6 +167,7 @@ export function uuid(args) {
144
167
  {
145
168
  isValid: false,
146
169
  code: 'uuid',
170
+ // eslint-disable-next-line ts/no-unnecessary-condition
147
171
  path: path || [],
148
172
  message: args.message
149
173
  }
@@ -154,8 +178,11 @@ export function uuid(args) {
154
178
  }
155
179
  export function email(args) {
156
180
  const emailRegex = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i;
181
+ console.log('aquiiiiii');
157
182
  return {
183
+ name: 'email',
158
184
  type: 'low',
185
+ // eslint-disable-next-line ts/require-await
159
186
  callback: async (value, path, _options)=>{
160
187
  const isValid = emailRegex.test(value);
161
188
  return {
@@ -164,6 +191,7 @@ export function email(args) {
164
191
  {
165
192
  isValid: false,
166
193
  code: 'email',
194
+ // eslint-disable-next-line ts/no-unnecessary-condition
167
195
  path: path || [],
168
196
  message: args.message
169
197
  }
@@ -1,6 +1,7 @@
1
1
  export function unionValidation(schemas) {
2
2
  return {
3
- type: 'high',
3
+ name: 'union',
4
+ type: 'medium',
4
5
  callback: async (value, path, options)=>{
5
6
  const parsedValues = {
6
7
  parsed: value,
@@ -22,8 +23,8 @@ export function unionValidation(schemas) {
22
23
  errors: []
23
24
  };
24
25
  } else if (startingToInternalBubbleUpLength < (options.toInternalToBubbleUp?.length || 0)) {
25
- // If there is a new toInternalToBubbleUp we should remove the ones that we added since this is not a valid schema,
26
- // we shouldn't be calling the `toInternal` on that schemas.
26
+ // If there is a new toInternalToBubbleUp we should remove the ones that we added since this is not a
27
+ // valid schema, we shouldn't be calling the `toInternal` on that schemas.
27
28
  const numberOfElementsToRemove = (options.toInternalToBubbleUp?.length || 0) - startingToInternalBubbleUpLength;
28
29
  options.toInternalToBubbleUp?.splice(startingToInternalBubbleUpLength, numberOfElementsToRemove);
29
30
  }
@@ -31,7 +32,7 @@ export function unionValidation(schemas) {
31
32
  return {
32
33
  parsed: parsedValues.parsed,
33
34
  // eslint-disable-next-line ts/no-unnecessary-condition
34
- errors: parsedValues.errors ? parsedValues.errors : []
35
+ errors: Array.isArray(parsedValues.errors) ? parsedValues.errors : []
35
36
  };
36
37
  }
37
38
  };
@@ -8,47 +8,61 @@ const typeByPriority = Object.entries(priorityByType).reduce((acc, [key, value])
8
8
  return acc;
9
9
  }, {});
10
10
  /**
11
- * Okay, so what is this? This is a validator class, it represents a Node on a linked list. The linked list has lower priority validators on the end of the list and higher
12
- * priority validators on the start of the list. Maybe in the future we can change that to a binary tree, but for now this is enough.
11
+ * Okay, so what is this? This is a validator class, it represents a Node on a linked list. The linked list
12
+ * has lower priority validators on the end of the list and higher priority validators on the start of the
13
+ * list. Maybe in the future we can change that to a binary tree, but for now this is enough.
13
14
  *
14
- * Why did we choose this approach? Because what i was doing was that i saw myself repeating the same code 3 times on the schema in order to make the validation work. Each validator had
15
- * a different return type, i didn't like that. I wanted to add more power and control on the validator, not on the schema. So i created this class. So pretty much, over here and
16
- * on each validator we can define the type it is. It can actually be three: `low`, `medium` and `high`. The `low` validators are the ones that are going to be executed last, the `high` validators
17
- * are the ones that are going to be executed first. High validators validate if the value is null or undefined, if it allows that. It can stop the execution of the other validators if it wants to.
15
+ * Why did we choose this approach? Because what i was doing was that i saw myself repeating the same code 3
16
+ * times on the schema in order to make the validation work. Each validator had a different return type, i
17
+ * didn't like that. I wanted to add more power and control on the validator, not on the schema. So i created
18
+ * this class. So pretty much, over here and on each validator we can define the type it is. It can actually
19
+ * be three: `low`, `medium` and `high`. The `low` validators are the ones that are going to be executed last,
20
+ * The `high` validators are the ones that are going to be executed first. High validators validate if the value
21
+ * is null or undefined, if it allows that. It can stop the execution of the other validators if it wants to.
18
22
  *
19
- * 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? No, right? So the high validator can stop the execution of the other validators.
20
- * Same as before, if the value is not a number, is there a reason to check if it's value is greater than the `max` allowed 10? No, right? So the medium validator can stop the execution of
21
- * the other validators.
23
+ * 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?
24
+ * No, right? So the high validator can stop the execution of the other validators.
25
+ * Same as before, if the value is not a number, is there a reason to check if it's value is greater than the
26
+ * `max` allowed 10? No, right? So the medium validator can stop the execution of the other validators.
22
27
  *
23
- * That's what this solve, it's a better approach than repeating the same code 3 times on the schema. It's also more powerful, because if we need to add any extra priorities we can do that easily
24
- * without changing the schema.
28
+ * That's what this solve, it's a better approach than repeating the same code 3 times on the schema. It's also
29
+ * more powerful, because if we need to add any extra priorities we can do that easily without changing the schema.
25
30
  */ export default class Validator {
26
31
  child;
27
32
  parent;
33
+ fallbackNamesAdded = new Set();
28
34
  priority;
29
35
  fallbacks = [];
30
36
  constructor(type){
37
+ this.fallbackNamesAdded = new Set();
38
+ this.fallbacks = [];
31
39
  this.priority = priorityByType[type];
32
40
  }
33
41
  /**
34
- * We create all of the validators on the schema in order, i actually didn't want to go on that route but i found it easier to do so.
42
+ * We create all of the validators on the schema in order, i actually didn't want to go on that route but i
43
+ * found it easier to do so.
35
44
  *
36
- * The logic here is simple, if it's not the same priority we will walk on the linked list until we find a validator that matches the priority we are expecting. If we can't walk anymore, we create
37
- * the next priority validator and append it to the linked list. Be aware that it's a double linked list, so we can walk both ways, from the end to the start and from the start to the end.
38
- * So you don't really need to start from the root, the linked list can start from anywhere and it will find it's way through.
45
+ * The logic here is simple, if it's not the same priority we will walk on the linked list until we find
46
+ * a validator that matches the priority we are expecting. If we can't walk anymore, we create the next
47
+ * priority validator and append it to the linked list. Be aware that it's a double linked list, so we
48
+ * can walk both ways, from the end to the start and from the start to the end.
49
+ * So you don't really need to start from the root, the linked list can start from anywhere and it will
50
+ * find it's way through.
39
51
  *
40
- * I know there are better ways to do this instead of walking through the linked list, but like i explained before, this is enough for now.
52
+ * I know there are better ways to do this instead of walking through the linked list, but like i explained
53
+ * before, this is enough for now.
41
54
  *
42
- * If the priority is higher than the current priority saved on the schema, we should substitute the rootValidator on the schema with the new one.
55
+ * If the priority is higher than the current priority saved on the schema, we should substitute the
56
+ * rootValidator on the schema with the new one.
43
57
  *
44
58
  * @param schema - The schema that we are working on right now, all fallbacks are tied to that specific schema.
45
59
  * @param type - The type of the fallback that we are adding.
46
60
  * @param fallback - The fallback function that we are adding.
47
61
  * @param childOrParent - If we are adding a fallback to the child or to the parent.
48
62
  * @param options - The options that we are passing to the fallback.
49
- */ checkAppendOrCreate(schema, type, fallback, childOrParent, options) {
63
+ */ checkAppendOrCreate(schema, type, fallbackName, fallback, childOrParent, options) {
50
64
  const schemaWithProtected = schema;
51
- if (this[childOrParent]) this[childOrParent].addFallback(schemaWithProtected, type, fallback, options);
65
+ if (this[childOrParent]) this[childOrParent].addFallback(schemaWithProtected, type, fallbackName, fallback, options);
52
66
  else {
53
67
  const nextPriority = childOrParent === 'child' ? this.priority - 1 : this.priority + 1;
54
68
  if (Object.keys(typeByPriority).includes(String(nextPriority))) {
@@ -56,24 +70,28 @@ const typeByPriority = Object.entries(priorityByType).reduce((acc, [key, value])
56
70
  const validatorInstance = new Validator(nextType);
57
71
  this[childOrParent] = validatorInstance;
58
72
  this[childOrParent][childOrParent === 'parent' ? 'child' : 'parent'] = this;
59
- this[childOrParent].addFallback(schemaWithProtected, type, fallback, options);
73
+ this[childOrParent].addFallback(schemaWithProtected, type, fallbackName, fallback, options);
60
74
  if (nextPriority > schemaWithProtected.__rootFallbacksValidator.priority) schemaWithProtected.__rootFallbacksValidator = validatorInstance;
61
75
  }
62
76
  }
63
77
  }
64
- addFallback(schema, type, fallback, options) {
78
+ addFallback(schema, type, fallbackName, fallback, options) {
79
+ if (this.fallbackNamesAdded.has(fallbackName) && options?.removeCurrent !== true) return;
80
+ this.fallbackNamesAdded.add(fallbackName);
65
81
  const priority = priorityByType[type];
66
82
  if (this.priority === priority) {
67
83
  if (typeof options?.at === 'number') this.fallbacks.splice(options.at, options.removeCurrent === true ? 1 : 0, fallback);
68
84
  else this.fallbacks.push(fallback);
69
- } else if (priority > this.priority) this.checkAppendOrCreate(schema, type, fallback, 'parent', options);
70
- else if (priority < this.priority) this.checkAppendOrCreate(schema, type, fallback, 'child', options);
85
+ } else if (priority > this.priority) this.checkAppendOrCreate(schema, type, fallbackName, fallback, 'parent', options);
86
+ else if (priority < this.priority) this.checkAppendOrCreate(schema, type, fallbackName, fallback, 'child', options);
71
87
  }
72
88
  /**
73
- * Validates the value against all of the fallbacks, the fallbacks are executed in order, from the highest priority to the lowest priority.
74
- * A validator can stop the execution of the other validators if it feels like so. Like on the example of a value being null or undefined.
89
+ * Validates the value against all of the fallbacks, the fallbacks are executed in order, from the highest
90
+ * priority to the lowest priority. A validator can stop the execution of the other validators if it feels
91
+ * like so. Like on the example of a value being null or undefined.
75
92
  *
76
- * @param errorsAsHashedSet - This is a set that contains all of the errors that we already found, this is used to avoid duplicated errors.
93
+ * @param errorsAsHashedSet - This is a set that contains all of the errors that we already found, this is
94
+ * used to avoid duplicated errors.
77
95
  * @param path - The path that we are validating right now.
78
96
  * @param parseResult - The result of the parsing, it contains the parsed value and the errors that we found.
79
97
  * @param options - The options that we are passing to the fallback.
@@ -84,25 +102,33 @@ const typeByPriority = Object.entries(priorityByType).reduce((acc, [key, value])
84
102
  parseResult.parsed = parsed;
85
103
  for (const error of errors){
86
104
  if (error.isValid === false) {
87
- const hashedError = JSON.stringify(error);
105
+ const sortedError = Object.fromEntries(Object.entries(error).sort(([a], [b])=>a.localeCompare(b)));
106
+ const hashedError = JSON.stringify(sortedError);
88
107
  if (errorsAsHashedSet.has(hashedError)) continue;
108
+ errorsAsHashedSet.add(hashedError);
89
109
  if (!Array.isArray(parseResult.errors)) parseResult.errors = [];
90
- parseResult.errors.push(error);
110
+ parseResult.errors.push({
111
+ ...error,
112
+ received: parseResult.parsed
113
+ });
91
114
  }
92
115
  }
93
116
  doesItShouldPreventChildValidation = doesItShouldPreventChildValidation || preventChildValidation || false;
94
117
  }
95
- if (this.child && doesItShouldPreventChildValidation === false) return this.child.validate(errorsAsHashedSet, path, parseResult, options);
118
+ if (this.child && doesItShouldPreventChildValidation === false) return await this.child.validate(errorsAsHashedSet, path, parseResult, options);
96
119
  return parseResult;
97
120
  }
98
121
  /**
99
- * This static method takes care of everything for you. This means that you should only call this method for appending new fallbacks, it takes care of creating the root validator
100
- * and making sure that the rootValidator on the schema is the highest priority one.
122
+ * This static method takes care of everything for you. This means that you should only call this method
123
+ * for appending new fallbacks, it takes care of creating the root validator and making sure that the
124
+ * rootValidator on the schema is the highest priority one.
101
125
  *
102
- * @param schema - The schema that we are working on right now, all fallbacks are tied to that specific schema. We automatically define the rootValidator on the schema
103
- * so you don't need to worry about that.
104
- * @param fallback - The fallback that we are adding. This is an object that contains the type of the fallback and the callback that we are adding.
105
- * @param options - The options that we are passing to the fallback. Options like `at` and `removeCurrent` are passed to the `addFallback` method.
126
+ * @param schema - The schema that we are working on right now, all fallbacks are tied to that specific
127
+ * schema. We automatically define the rootValidator on the schema so you don't need to worry about that.
128
+ * @param fallback - The fallback that we are adding. This is an object that contains the type of the
129
+ * fallback and the callback that we are adding.
130
+ * @param options - The options that we are passing to the fallback. Options like `at` and `removeCurrent`
131
+ * are passed to the `addFallback` method.
106
132
  */ static createAndAppendFallback(schema, fallback, options) {
107
133
  const schemaWithProtected = schema;
108
134
  let validatorInstance = schemaWithProtected.__rootFallbacksValidator;
@@ -111,7 +137,7 @@ const typeByPriority = Object.entries(priorityByType).reduce((acc, [key, value])
111
137
  validatorInstance = new Validator(fallback.type);
112
138
  schemaWithProtected.__rootFallbacksValidator = validatorInstance;
113
139
  }
114
- validatorInstance.addFallback(schema, fallback.type, fallback.callback, options);
140
+ validatorInstance.addFallback(schema, fallback.type, fallback.name, fallback.callback, options);
115
141
  return validatorInstance;
116
142
  }
117
143
  toString(ident = 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@palmares/schemas",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "description": "This defines a default schema definition for validation of data, it abstract popular schema validation libraries like zod, yup, valibot and others\"",
5
5
  "main": "./dist/cjs/src/index.js",
6
6
  "module": "./dist/esm/src/index.js",
@@ -31,8 +31,8 @@
31
31
  },
32
32
  "homepage": "https://github.com/palmaresHQ/palmares#readme",
33
33
  "dependencies": {
34
- "@palmares/databases": "0.0.2",
35
- "@palmares/core": "0.0.4"
34
+ "@palmares/core": "0.1.0",
35
+ "@palmares/databases": "0.1.0"
36
36
  },
37
37
  "scripts": {
38
38
  "clear": "rimraf ./dist",
@@ -1,7 +1,7 @@
1
1
  import FieldAdapter from '.';
2
2
 
3
3
  import type WithFallback from '../../utils';
4
- import type { NumberAdapterTranslateArgs } from '../types';
4
+ import type { ArrayAdapterTranslateArgs, NumberAdapterTranslateArgs } from '../types';
5
5
 
6
6
  export function arrayFieldAdapter<
7
7
  TTranslate extends ArrayFieldAdapter['translate'],
@@ -27,5 +27,5 @@ export function arrayFieldAdapter<
27
27
  }
28
28
 
29
29
  export default class ArrayFieldAdapter extends FieldAdapter {
30
- translate(_fieldAdapter: FieldAdapter, _args: NumberAdapterTranslateArgs): any | WithFallback<'array'> {}
30
+ translate(_fieldAdapter: FieldAdapter, _args: ArrayAdapterTranslateArgs): any | WithFallback<'array'> {}
31
31
  }
@@ -10,12 +10,7 @@ export function booleanFieldAdapter<
10
10
  TToString extends BooleanFieldAdapter['toString'],
11
11
  TFormatError extends BooleanFieldAdapter['formatError'],
12
12
  TParse extends BooleanFieldAdapter['parse']
13
- >(args: {
14
- translate: TTranslate;
15
- toString?: TToString;
16
- formatError?: TFormatError;
17
- parse?: TParse;
18
- }) {
13
+ >(args: { translate: TTranslate; toString?: TToString; formatError?: TFormatError; parse?: TParse }) {
19
14
  class CustomBooleanFieldAdapter extends BooleanFieldAdapter {
20
15
  translate = args.translate;
21
16
  toString = args.toString as TToString;
@@ -29,8 +24,8 @@ export function booleanFieldAdapter<
29
24
  toString: TToString;
30
25
  formatError: TFormatError;
31
26
  parse: TParse;
32
- }
33
- }
27
+ };
28
+ };
34
29
  }
35
30
 
36
31
  export default class BooleanFieldAdapter extends FieldAdapter {
@@ -5,18 +5,12 @@ import type SchemaAdapter from '..';
5
5
  import type WithFallback from '../../utils';
6
6
  import type { DatetimeAdapterTranslateArgs } from '../types';
7
7
 
8
-
9
8
  export function datetimeFieldAdapter<
10
9
  TTranslate extends DatetimeFieldAdapter['translate'],
11
10
  TToString extends DatetimeFieldAdapter['toString'],
12
11
  TFormatError extends DatetimeFieldAdapter['formatError'],
13
12
  TParse extends DatetimeFieldAdapter['parse']
14
- >(args: {
15
- translate: TTranslate;
16
- toString?: TToString;
17
- formatError?: TFormatError;
18
- parse?: TParse;
19
- }) {
13
+ >(args: { translate: TTranslate; toString?: TToString; formatError?: TFormatError; parse?: TParse }) {
20
14
  class CustomDatetimeFieldAdapter extends DatetimeFieldAdapter {
21
15
  translate = args.translate;
22
16
  toString = args.toString as TToString;
@@ -30,8 +24,8 @@ export function datetimeFieldAdapter<
30
24
  toString: TToString;
31
25
  formatError: TFormatError;
32
26
  parse: TParse;
33
- }
34
- }
27
+ };
28
+ };
35
29
  }
36
30
 
37
31
  export default class DatetimeFieldAdapter extends FieldAdapter {
@@ -10,12 +10,7 @@ export function fieldAdapter<
10
10
  TToString extends FieldAdapter['toString'],
11
11
  TFormatError extends FieldAdapter['formatError'],
12
12
  TParse extends FieldAdapter['parse']
13
- >(args: {
14
- translate: TTranslate;
15
- toString?: TToString;
16
- formatError?: TFormatError;
17
- parse?: TParse;
18
- }) {
13
+ >(args: { translate: TTranslate; toString?: TToString; formatError?: TFormatError; parse?: TParse }) {
19
14
  class CustomFieldAdapter extends FieldAdapter {
20
15
  translate = args.translate;
21
16
  toString = args.toString as TToString;
@@ -29,20 +24,24 @@ export function fieldAdapter<
29
24
  toString: TToString;
30
25
  formatError: TFormatError;
31
26
  parse: TParse;
32
- }
33
- }
27
+ };
28
+ };
34
29
  }
35
30
  export default class FieldAdapter {
36
- translate(_fieldAdapter: FieldAdapter, _args: AdapterTranslateArgs<SupportedSchemas>, _base?: any): any | WithFallback<SupportedSchemas> {
31
+ translate(
32
+ _fieldAdapter: FieldAdapter,
33
+ _args: AdapterTranslateArgs<SupportedSchemas>,
34
+ _base?: any
35
+ ): any | WithFallback<SupportedSchemas> {
37
36
  throw new SchemaAdapterNotImplementedError({ className: this.constructor.name, functionName: 'translate' });
38
37
  }
39
38
 
40
39
  parse(
41
40
  _adapter: SchemaAdapter,
42
41
  _fieldAdapter: FieldAdapter,
43
- _result: any,
42
+ _schema: any,
44
43
  _value: any,
45
- _args: Omit<AdapterTranslateArgs<SupportedSchemas>, 'withFallback'>,
44
+ _args: Omit<AdapterTranslateArgs<SupportedSchemas>, 'withFallback'>
46
45
  ): Promise<{ errors: any; parsed: any }> {
47
46
  throw new SchemaAdapterNotImplementedError({ className: this.constructor.name, functionName: 'parse' });
48
47
  }
@@ -60,6 +59,7 @@ export default class FieldAdapter {
60
59
  async formatError(
61
60
  _adapter: SchemaAdapter,
62
61
  _fieldAdapter: FieldAdapter,
62
+ _schema: any,
63
63
  _error: any,
64
64
  _metadata?: any
65
65
  ): Promise<{
@@ -5,18 +5,12 @@ import type SchemaAdapter from '..';
5
5
  import type WithFallback from '../../utils';
6
6
  import type { NumberAdapterTranslateArgs } from '../types';
7
7
 
8
-
9
8
  export function numberFieldAdapter<
10
9
  TTranslate extends NumberFieldAdapter['translate'],
11
10
  TToString extends NumberFieldAdapter['toString'],
12
11
  TFormatError extends NumberFieldAdapter['formatError'],
13
12
  TParse extends NumberFieldAdapter['parse']
14
- >(args: {
15
- translate: TTranslate;
16
- toString?: TToString;
17
- formatError?: TFormatError;
18
- parse?: TParse;
19
- }) {
13
+ >(args: { translate: TTranslate; toString?: TToString; formatError?: TFormatError; parse?: TParse }) {
20
14
  class CustomNumberFieldAdapter extends NumberFieldAdapter {
21
15
  translate = args.translate;
22
16
  toString = args.toString as TToString;
@@ -30,8 +24,8 @@ export function numberFieldAdapter<
30
24
  toString: TToString;
31
25
  formatError: TFormatError;
32
26
  parse: TParse;
33
- }
34
- }
27
+ };
28
+ };
35
29
  }
36
30
 
37
31
  export default class NumberFieldAdapter extends FieldAdapter {
@@ -3,20 +3,14 @@ import { SchemaAdapterNotImplementedError } from '../../exceptions';
3
3
 
4
4
  import type SchemaAdapter from '..';
5
5
  import type WithFallback from '../../utils';
6
- import type { ObjectAdapterTranslateArgs } from '../types';
7
-
6
+ import type { ObjectAdapterToStringArgs, ObjectAdapterTranslateArgs } from '../types';
8
7
 
9
8
  export function objectFieldAdapter<
10
9
  TTranslate extends ObjectFieldAdapter['translate'],
11
10
  TToString extends ObjectFieldAdapter['toString'],
12
11
  TFormatError extends ObjectFieldAdapter['formatError'],
13
12
  TParse extends ObjectFieldAdapter['parse']
14
- >(args: {
15
- translate: TTranslate;
16
- toString?: TToString;
17
- formatError?: TFormatError;
18
- parse?: TParse;
19
- }) {
13
+ >(args: { translate: TTranslate; toString?: TToString; formatError?: TFormatError; parse?: TParse }) {
20
14
  class CustomObjectFieldAdapter extends ObjectFieldAdapter {
21
15
  translate = args.translate;
22
16
  toString = args.toString as TToString;
@@ -30,8 +24,8 @@ export function objectFieldAdapter<
30
24
  toString: TToString;
31
25
  formatError: TFormatError;
32
26
  parse: TParse;
33
- }
34
- }
27
+ };
28
+ };
35
29
  }
36
30
 
37
31
  export default class ObjectFieldAdapter extends FieldAdapter {
@@ -46,4 +40,13 @@ export default class ObjectFieldAdapter extends FieldAdapter {
46
40
  ): Promise<{ errors: any; parsed: any }> {
47
41
  throw new SchemaAdapterNotImplementedError({ className: this.constructor.name, functionName: 'parse' });
48
42
  }
43
+
44
+ toString(
45
+ _adapter: SchemaAdapter,
46
+ _fieldAdapter: FieldAdapter,
47
+ _args: ObjectAdapterToStringArgs,
48
+ _base?: any
49
+ ): Promise<string> {
50
+ throw new SchemaAdapterNotImplementedError({ className: this.constructor.name, functionName: 'toString' });
51
+ }
49
52
  }
@@ -5,18 +5,12 @@ import type SchemaAdapter from '..';
5
5
  import type WithFallback from '../../utils';
6
6
  import type { StringAdapterTranslateArgs } from '../types';
7
7
 
8
-
9
8
  export function stringFieldAdapter<
10
9
  TTranslate extends StringFieldAdapter['translate'],
11
10
  TToString extends StringFieldAdapter['toString'],
12
11
  TFormatError extends StringFieldAdapter['formatError'],
13
12
  TParse extends StringFieldAdapter['parse']
14
- >(args: {
15
- translate: TTranslate;
16
- toString?: TToString;
17
- formatError?: TFormatError;
18
- parse?: TParse;
19
- }) {
13
+ >(args: { translate: TTranslate; toString?: TToString; formatError?: TFormatError; parse?: TParse }) {
20
14
  class CustomStringFieldAdapter extends StringFieldAdapter {
21
15
  translate = args.translate;
22
16
  toString = args.toString as TToString;
@@ -30,8 +24,8 @@ export function stringFieldAdapter<
30
24
  toString: TToString;
31
25
  formatError: TFormatError;
32
26
  parse: TParse;
33
- }
34
- }
27
+ };
28
+ };
35
29
  }
36
30
 
37
31
  export default class StringFieldAdapter extends FieldAdapter {