@palmares/schemas 0.0.1

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 (219) hide show
  1. package/.turbo/turbo-build$colon$watch.log +424 -0
  2. package/.turbo/turbo-build.log +13 -0
  3. package/.turbo/turbo-build:watch.log +26 -0
  4. package/CHANGELOG.md +11 -0
  5. package/LICENSE +21 -0
  6. package/dist/cjs/src/adapter/fields/array.js +157 -0
  7. package/dist/cjs/src/adapter/fields/boolean.js +167 -0
  8. package/dist/cjs/src/adapter/fields/datetime.js +167 -0
  9. package/dist/cjs/src/adapter/fields/index.js +311 -0
  10. package/dist/cjs/src/adapter/fields/number.js +167 -0
  11. package/dist/cjs/src/adapter/fields/object.js +167 -0
  12. package/dist/cjs/src/adapter/fields/string.js +167 -0
  13. package/dist/cjs/src/adapter/fields/union.js +167 -0
  14. package/dist/cjs/src/adapter/index.js +198 -0
  15. package/dist/cjs/src/adapter/types.js +4 -0
  16. package/dist/cjs/src/compile.js +262 -0
  17. package/dist/cjs/src/conf.js +27 -0
  18. package/dist/cjs/src/constants.js +42 -0
  19. package/dist/cjs/src/domain.js +12 -0
  20. package/dist/cjs/src/exceptions.js +168 -0
  21. package/dist/cjs/src/index.js +365 -0
  22. package/dist/cjs/src/model.js +628 -0
  23. package/dist/cjs/src/parsers/convert-from-number.js +20 -0
  24. package/dist/cjs/src/parsers/convert-from-string.js +24 -0
  25. package/dist/cjs/src/parsers/index.js +25 -0
  26. package/dist/cjs/src/schema/array.js +890 -0
  27. package/dist/cjs/src/schema/boolean.js +826 -0
  28. package/dist/cjs/src/schema/datetime.js +778 -0
  29. package/dist/cjs/src/schema/index.js +17 -0
  30. package/dist/cjs/src/schema/number.js +960 -0
  31. package/dist/cjs/src/schema/object.js +999 -0
  32. package/dist/cjs/src/schema/schema.js +1788 -0
  33. package/dist/cjs/src/schema/string.js +948 -0
  34. package/dist/cjs/src/schema/types.js +4 -0
  35. package/dist/cjs/src/schema/union.js +952 -0
  36. package/dist/cjs/src/types.js +4 -0
  37. package/dist/cjs/src/utils.js +627 -0
  38. package/dist/cjs/src/validators/array.js +457 -0
  39. package/dist/cjs/src/validators/boolean.js +199 -0
  40. package/dist/cjs/src/validators/datetime.js +287 -0
  41. package/dist/cjs/src/validators/number.js +403 -0
  42. package/dist/cjs/src/validators/object.js +290 -0
  43. package/dist/cjs/src/validators/schema.js +318 -0
  44. package/dist/cjs/src/validators/string.js +439 -0
  45. package/dist/cjs/src/validators/types.js +4 -0
  46. package/dist/cjs/src/validators/union.js +232 -0
  47. package/dist/cjs/src/validators/utils.js +426 -0
  48. package/dist/cjs/tsconfig.types.tsbuildinfo +1 -0
  49. package/dist/cjs/types/adapter/fields/array.d.ts +20 -0
  50. package/dist/cjs/types/adapter/fields/array.d.ts.map +1 -0
  51. package/dist/cjs/types/adapter/fields/boolean.d.ts +25 -0
  52. package/dist/cjs/types/adapter/fields/boolean.d.ts.map +1 -0
  53. package/dist/cjs/types/adapter/fields/datetime.d.ts +25 -0
  54. package/dist/cjs/types/adapter/fields/datetime.d.ts.map +1 -0
  55. package/dist/cjs/types/adapter/fields/index.d.ts +31 -0
  56. package/dist/cjs/types/adapter/fields/index.d.ts.map +1 -0
  57. package/dist/cjs/types/adapter/fields/number.d.ts +25 -0
  58. package/dist/cjs/types/adapter/fields/number.d.ts.map +1 -0
  59. package/dist/cjs/types/adapter/fields/object.d.ts +25 -0
  60. package/dist/cjs/types/adapter/fields/object.d.ts.map +1 -0
  61. package/dist/cjs/types/adapter/fields/string.d.ts +25 -0
  62. package/dist/cjs/types/adapter/fields/string.d.ts.map +1 -0
  63. package/dist/cjs/types/adapter/fields/union.d.ts +25 -0
  64. package/dist/cjs/types/adapter/fields/union.d.ts.map +1 -0
  65. package/dist/cjs/types/adapter/index.d.ts +25 -0
  66. package/dist/cjs/types/adapter/index.d.ts.map +1 -0
  67. package/dist/cjs/types/adapter/types.d.ts +144 -0
  68. package/dist/cjs/types/adapter/types.d.ts.map +1 -0
  69. package/dist/cjs/types/compile.d.ts +3 -0
  70. package/dist/cjs/types/compile.d.ts.map +1 -0
  71. package/dist/cjs/types/conf.d.ts +16 -0
  72. package/dist/cjs/types/conf.d.ts.map +1 -0
  73. package/dist/cjs/types/constants.d.ts +6 -0
  74. package/dist/cjs/types/constants.d.ts.map +1 -0
  75. package/dist/cjs/types/domain.d.ts +21 -0
  76. package/dist/cjs/types/domain.d.ts.map +1 -0
  77. package/dist/cjs/types/exceptions.d.ts +13 -0
  78. package/dist/cjs/types/exceptions.d.ts.map +1 -0
  79. package/dist/cjs/types/index.d.ts +240 -0
  80. package/dist/cjs/types/index.d.ts.map +1 -0
  81. package/dist/cjs/types/model.d.ts +136 -0
  82. package/dist/cjs/types/model.d.ts.map +1 -0
  83. package/dist/cjs/types/parsers/convert-from-number.d.ts +15 -0
  84. package/dist/cjs/types/parsers/convert-from-number.d.ts.map +1 -0
  85. package/dist/cjs/types/parsers/convert-from-string.d.ts +9 -0
  86. package/dist/cjs/types/parsers/convert-from-string.d.ts.map +1 -0
  87. package/dist/cjs/types/parsers/index.d.ts +3 -0
  88. package/dist/cjs/types/parsers/index.d.ts.map +1 -0
  89. package/dist/cjs/types/schema/array.d.ts +429 -0
  90. package/dist/cjs/types/schema/array.d.ts.map +1 -0
  91. package/dist/cjs/types/schema/boolean.d.ts +501 -0
  92. package/dist/cjs/types/schema/boolean.d.ts.map +1 -0
  93. package/dist/cjs/types/schema/datetime.d.ts +474 -0
  94. package/dist/cjs/types/schema/datetime.d.ts.map +1 -0
  95. package/dist/cjs/types/schema/index.d.ts +4 -0
  96. package/dist/cjs/types/schema/index.d.ts.map +1 -0
  97. package/dist/cjs/types/schema/number.d.ts +667 -0
  98. package/dist/cjs/types/schema/number.d.ts.map +1 -0
  99. package/dist/cjs/types/schema/object.d.ts +450 -0
  100. package/dist/cjs/types/schema/object.d.ts.map +1 -0
  101. package/dist/cjs/types/schema/schema.d.ts +646 -0
  102. package/dist/cjs/types/schema/schema.d.ts.map +1 -0
  103. package/dist/cjs/types/schema/string.d.ts +606 -0
  104. package/dist/cjs/types/schema/string.d.ts.map +1 -0
  105. package/dist/cjs/types/schema/types.d.ts +70 -0
  106. package/dist/cjs/types/schema/types.d.ts.map +1 -0
  107. package/dist/cjs/types/schema/union.d.ts +388 -0
  108. package/dist/cjs/types/schema/union.d.ts.map +1 -0
  109. package/dist/cjs/types/types.d.ts +11 -0
  110. package/dist/cjs/types/types.d.ts.map +1 -0
  111. package/dist/cjs/types/utils.d.ts +79 -0
  112. package/dist/cjs/types/utils.d.ts.map +1 -0
  113. package/dist/cjs/types/validators/array.d.ts +8 -0
  114. package/dist/cjs/types/validators/array.d.ts.map +1 -0
  115. package/dist/cjs/types/validators/boolean.d.ts +4 -0
  116. package/dist/cjs/types/validators/boolean.d.ts.map +1 -0
  117. package/dist/cjs/types/validators/datetime.d.ts +7 -0
  118. package/dist/cjs/types/validators/datetime.d.ts.map +1 -0
  119. package/dist/cjs/types/validators/number.d.ts +10 -0
  120. package/dist/cjs/types/validators/number.d.ts.map +1 -0
  121. package/dist/cjs/types/validators/object.d.ts +6 -0
  122. package/dist/cjs/types/validators/object.d.ts.map +1 -0
  123. package/dist/cjs/types/validators/schema.d.ts +10 -0
  124. package/dist/cjs/types/validators/schema.d.ts.map +1 -0
  125. package/dist/cjs/types/validators/string.d.ts +12 -0
  126. package/dist/cjs/types/validators/string.d.ts.map +1 -0
  127. package/dist/cjs/types/validators/types.d.ts +2 -0
  128. package/dist/cjs/types/validators/types.d.ts.map +1 -0
  129. package/dist/cjs/types/validators/union.d.ts +4 -0
  130. package/dist/cjs/types/validators/union.d.ts.map +1 -0
  131. package/dist/cjs/types/validators/utils.d.ts +83 -0
  132. package/dist/cjs/types/validators/utils.d.ts.map +1 -0
  133. package/dist/esm/src/adapter/fields/array.js +13 -0
  134. package/dist/esm/src/adapter/fields/boolean.js +20 -0
  135. package/dist/esm/src/adapter/fields/datetime.js +20 -0
  136. package/dist/esm/src/adapter/fields/index.js +37 -0
  137. package/dist/esm/src/adapter/fields/number.js +20 -0
  138. package/dist/esm/src/adapter/fields/object.js +20 -0
  139. package/dist/esm/src/adapter/fields/string.js +20 -0
  140. package/dist/esm/src/adapter/fields/union.js +20 -0
  141. package/dist/esm/src/adapter/index.js +18 -0
  142. package/dist/esm/src/adapter/types.js +1 -0
  143. package/dist/esm/src/compile.js +10 -0
  144. package/dist/esm/src/conf.js +19 -0
  145. package/dist/esm/src/constants.js +5 -0
  146. package/dist/esm/src/domain.js +2 -0
  147. package/dist/esm/src/exceptions.js +15 -0
  148. package/dist/esm/src/index.js +160 -0
  149. package/dist/esm/src/model.js +255 -0
  150. package/dist/esm/src/parsers/convert-from-number.js +8 -0
  151. package/dist/esm/src/parsers/convert-from-string.js +14 -0
  152. package/dist/esm/src/parsers/index.js +2 -0
  153. package/dist/esm/src/schema/array.js +403 -0
  154. package/dist/esm/src/schema/boolean.js +465 -0
  155. package/dist/esm/src/schema/datetime.js +423 -0
  156. package/dist/esm/src/schema/index.js +3 -0
  157. package/dist/esm/src/schema/number.js +592 -0
  158. package/dist/esm/src/schema/object.js +464 -0
  159. package/dist/esm/src/schema/schema.js +728 -0
  160. package/dist/esm/src/schema/string.js +579 -0
  161. package/dist/esm/src/schema/types.js +1 -0
  162. package/dist/esm/src/schema/union.js +388 -0
  163. package/dist/esm/src/types.js +1 -0
  164. package/dist/esm/src/utils.js +175 -0
  165. package/dist/esm/src/validators/array.js +135 -0
  166. package/dist/esm/src/validators/boolean.js +35 -0
  167. package/dist/esm/src/validators/datetime.js +85 -0
  168. package/dist/esm/src/validators/number.js +162 -0
  169. package/dist/esm/src/validators/object.js +38 -0
  170. package/dist/esm/src/validators/schema.js +114 -0
  171. package/dist/esm/src/validators/string.js +174 -0
  172. package/dist/esm/src/validators/types.js +1 -0
  173. package/dist/esm/src/validators/union.js +38 -0
  174. package/dist/esm/src/validators/utils.js +120 -0
  175. package/package.json +48 -0
  176. package/src/adapter/fields/array.ts +31 -0
  177. package/src/adapter/fields/boolean.ts +48 -0
  178. package/src/adapter/fields/datetime.ts +49 -0
  179. package/src/adapter/fields/index.ts +72 -0
  180. package/src/adapter/fields/number.ts +49 -0
  181. package/src/adapter/fields/object.ts +49 -0
  182. package/src/adapter/fields/string.ts +49 -0
  183. package/src/adapter/fields/union.ts +49 -0
  184. package/src/adapter/index.ts +34 -0
  185. package/src/adapter/types.ts +261 -0
  186. package/src/compile.ts +14 -0
  187. package/src/conf.ts +27 -0
  188. package/src/constants.ts +9 -0
  189. package/src/domain.ts +3 -0
  190. package/src/exceptions.ts +17 -0
  191. package/src/index.ts +338 -0
  192. package/src/model.ts +501 -0
  193. package/src/parsers/convert-from-number.ts +13 -0
  194. package/src/parsers/convert-from-string.ts +19 -0
  195. package/src/parsers/index.ts +2 -0
  196. package/src/schema/array.ts +633 -0
  197. package/src/schema/boolean.ts +700 -0
  198. package/src/schema/datetime.ts +613 -0
  199. package/src/schema/index.ts +5 -0
  200. package/src/schema/number.ts +885 -0
  201. package/src/schema/object.ts +699 -0
  202. package/src/schema/schema.ts +1093 -0
  203. package/src/schema/string.ts +807 -0
  204. package/src/schema/types.ts +126 -0
  205. package/src/schema/union.ts +596 -0
  206. package/src/types.ts +13 -0
  207. package/src/utils.ts +322 -0
  208. package/src/validators/array.ts +164 -0
  209. package/src/validators/boolean.ts +46 -0
  210. package/src/validators/datetime.ts +113 -0
  211. package/src/validators/number.ts +188 -0
  212. package/src/validators/object.ts +55 -0
  213. package/src/validators/schema.ts +134 -0
  214. package/src/validators/string.ts +215 -0
  215. package/src/validators/types.ts +1 -0
  216. package/src/validators/union.ts +52 -0
  217. package/src/validators/utils.ts +200 -0
  218. package/tsconfig.json +9 -0
  219. package/tsconfig.types.json +10 -0
@@ -0,0 +1,174 @@
1
+ export function stringValidation() {
2
+ return {
3
+ type: 'medium',
4
+ callback: async (value, path, _options)=>{
5
+ return {
6
+ parsed: value,
7
+ errors: typeof value === 'string' ? [] : [
8
+ {
9
+ isValid: typeof value === 'string',
10
+ code: 'string',
11
+ path: path || [],
12
+ message: 'The value must be a string. Received: ' + typeof value
13
+ }
14
+ ]
15
+ };
16
+ }
17
+ };
18
+ }
19
+ export function maxLength(args) {
20
+ return {
21
+ type: 'low',
22
+ callback: async (value, path, _options)=>{
23
+ const isValid = args.inclusive ? value.length <= args.value : value.length < args.value;
24
+ return {
25
+ parsed: value,
26
+ errors: isValid ? [] : [
27
+ {
28
+ isValid: false,
29
+ code: 'maxLength',
30
+ path: path || [],
31
+ message: args.message
32
+ }
33
+ ]
34
+ };
35
+ }
36
+ };
37
+ }
38
+ export function minLength(args) {
39
+ return {
40
+ type: 'low',
41
+ callback: async (value, path, _options)=>{
42
+ const isValid = args.inclusive ? value.length >= args.value : value.length > args.value;
43
+ return {
44
+ parsed: value,
45
+ errors: isValid ? [] : [
46
+ {
47
+ isValid: false,
48
+ code: 'minLength',
49
+ path: path || [],
50
+ message: args.message
51
+ }
52
+ ]
53
+ };
54
+ }
55
+ };
56
+ }
57
+ export function endsWith(args) {
58
+ return {
59
+ type: 'low',
60
+ callback: async (value, path, _options)=>{
61
+ const isValid = value.endsWith(args.value);
62
+ return {
63
+ parsed: value,
64
+ errors: isValid ? [] : [
65
+ {
66
+ isValid: false,
67
+ code: 'endsWith',
68
+ path: path || [],
69
+ message: args.message
70
+ }
71
+ ]
72
+ };
73
+ }
74
+ };
75
+ }
76
+ export function startsWith(args) {
77
+ return {
78
+ type: 'low',
79
+ callback: async (value, path, _options)=>{
80
+ const isValid = value.startsWith(args.value);
81
+ return {
82
+ parsed: value,
83
+ errors: isValid ? [] : [
84
+ {
85
+ isValid: false,
86
+ code: 'startsWith',
87
+ path: path || [],
88
+ message: args.message
89
+ }
90
+ ]
91
+ };
92
+ }
93
+ };
94
+ }
95
+ export function includes(args) {
96
+ return {
97
+ type: 'low',
98
+ callback: async (value, path, _options)=>{
99
+ const isValid = value.includes(args.value);
100
+ return {
101
+ parsed: value,
102
+ errors: isValid ? [] : [
103
+ {
104
+ isValid: false,
105
+ code: 'includes',
106
+ path: path || [],
107
+ message: args.message
108
+ }
109
+ ]
110
+ };
111
+ }
112
+ };
113
+ }
114
+ export function regex(args) {
115
+ return {
116
+ type: 'low',
117
+ callback: async (value, path, _options)=>{
118
+ const isValid = args.value.test(value);
119
+ return {
120
+ parsed: value,
121
+ errors: isValid ? [] : [
122
+ {
123
+ isValid: false,
124
+ code: 'regex',
125
+ path: path || [],
126
+ message: args.message
127
+ }
128
+ ]
129
+ };
130
+ }
131
+ };
132
+ }
133
+ export function uuid(args) {
134
+ // const uuidRegex =
135
+ // /^([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
+ 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
+ return {
138
+ type: 'low',
139
+ callback: async (value, path, _options)=>{
140
+ const isValid = uuidRegex.test(value);
141
+ return {
142
+ parsed: value,
143
+ errors: isValid ? [] : [
144
+ {
145
+ isValid: false,
146
+ code: 'uuid',
147
+ path: path || [],
148
+ message: args.message
149
+ }
150
+ ]
151
+ };
152
+ }
153
+ };
154
+ }
155
+ export function email(args) {
156
+ const emailRegex = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i;
157
+ return {
158
+ type: 'low',
159
+ callback: async (value, path, _options)=>{
160
+ const isValid = emailRegex.test(value);
161
+ return {
162
+ parsed: value,
163
+ errors: isValid ? [] : [
164
+ {
165
+ isValid: false,
166
+ code: 'email',
167
+ path: path || [],
168
+ message: args.message
169
+ }
170
+ ]
171
+ };
172
+ }
173
+ };
174
+ }
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,38 @@
1
+ export function unionValidation(schemas) {
2
+ return {
3
+ type: 'high',
4
+ callback: async (value, path, options)=>{
5
+ const parsedValues = {
6
+ parsed: value,
7
+ errors: []
8
+ };
9
+ const startingToInternalBubbleUpLength = options.toInternalToBubbleUp?.length || 0;
10
+ // eslint-disable-next-line ts/prefer-for-of
11
+ for(let i = 0; i < schemas.length; i++){
12
+ const schemaWithProtected = schemas[i];
13
+ const parsedData = await schemaWithProtected.__parse(value, path, options);
14
+ parsedValues.parsed = parsedData.parsed;
15
+ if (Array.isArray(parsedData.errors)) if (Array.isArray(parsedValues.errors)) parsedValues.errors.push(...parsedData.errors);
16
+ else parsedValues.errors = parsedData.errors;
17
+ const hasNoErrorsSoItsAValidSchemaAndShouldResetOldErrors = // eslint-disable-next-line ts/no-unnecessary-condition
18
+ parsedData.errors === undefined || (parsedData.errors || []).length === 0;
19
+ if (hasNoErrorsSoItsAValidSchemaAndShouldResetOldErrors) {
20
+ return {
21
+ parsed: parsedValues.parsed,
22
+ errors: []
23
+ };
24
+ } 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.
27
+ const numberOfElementsToRemove = (options.toInternalToBubbleUp?.length || 0) - startingToInternalBubbleUpLength;
28
+ options.toInternalToBubbleUp?.splice(startingToInternalBubbleUpLength, numberOfElementsToRemove);
29
+ }
30
+ }
31
+ return {
32
+ parsed: parsedValues.parsed,
33
+ // eslint-disable-next-line ts/no-unnecessary-condition
34
+ errors: parsedValues.errors ? parsedValues.errors : []
35
+ };
36
+ }
37
+ };
38
+ }
@@ -0,0 +1,120 @@
1
+ const priorityByType = {
2
+ low: 0,
3
+ medium: 1,
4
+ high: 2
5
+ };
6
+ const typeByPriority = Object.entries(priorityByType).reduce((acc, [key, value])=>{
7
+ acc[value] = key;
8
+ return acc;
9
+ }, {});
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.
13
+ *
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.
18
+ *
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.
22
+ *
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.
25
+ */ export default class Validator {
26
+ child;
27
+ parent;
28
+ priority;
29
+ fallbacks = [];
30
+ constructor(type){
31
+ this.priority = priorityByType[type];
32
+ }
33
+ /**
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.
35
+ *
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.
39
+ *
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.
41
+ *
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.
43
+ *
44
+ * @param schema - The schema that we are working on right now, all fallbacks are tied to that specific schema.
45
+ * @param type - The type of the fallback that we are adding.
46
+ * @param fallback - The fallback function that we are adding.
47
+ * @param childOrParent - If we are adding a fallback to the child or to the parent.
48
+ * @param options - The options that we are passing to the fallback.
49
+ */ checkAppendOrCreate(schema, type, fallback, childOrParent, options) {
50
+ const schemaWithProtected = schema;
51
+ if (this[childOrParent]) this[childOrParent].addFallback(schemaWithProtected, type, fallback, options);
52
+ else {
53
+ const nextPriority = childOrParent === 'child' ? this.priority - 1 : this.priority + 1;
54
+ if (Object.keys(typeByPriority).includes(String(nextPriority))) {
55
+ const nextType = typeByPriority[nextPriority];
56
+ const validatorInstance = new Validator(nextType);
57
+ this[childOrParent] = validatorInstance;
58
+ this[childOrParent][childOrParent === 'parent' ? 'child' : 'parent'] = this;
59
+ this[childOrParent].addFallback(schemaWithProtected, type, fallback, options);
60
+ if (nextPriority > schemaWithProtected.__rootFallbacksValidator.priority) schemaWithProtected.__rootFallbacksValidator = validatorInstance;
61
+ }
62
+ }
63
+ }
64
+ addFallback(schema, type, fallback, options) {
65
+ const priority = priorityByType[type];
66
+ if (this.priority === priority) {
67
+ if (typeof options?.at === 'number') this.fallbacks.splice(options.at, options.removeCurrent === true ? 1 : 0, fallback);
68
+ 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);
71
+ }
72
+ /**
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.
75
+ *
76
+ * @param errorsAsHashedSet - This is a set that contains all of the errors that we already found, this is used to avoid duplicated errors.
77
+ * @param path - The path that we are validating right now.
78
+ * @param parseResult - The result of the parsing, it contains the parsed value and the errors that we found.
79
+ * @param options - The options that we are passing to the fallback.
80
+ */ async validate(errorsAsHashedSet, path, parseResult, options) {
81
+ let doesItShouldPreventChildValidation = false;
82
+ for (const fallback of this.fallbacks){
83
+ const { parsed, errors, preventChildValidation } = await fallback(parseResult.parsed, path, options);
84
+ parseResult.parsed = parsed;
85
+ for (const error of errors){
86
+ if (error.isValid === false) {
87
+ const hashedError = JSON.stringify(error);
88
+ if (errorsAsHashedSet.has(hashedError)) continue;
89
+ if (!Array.isArray(parseResult.errors)) parseResult.errors = [];
90
+ parseResult.errors.push(error);
91
+ }
92
+ }
93
+ doesItShouldPreventChildValidation = doesItShouldPreventChildValidation || preventChildValidation || false;
94
+ }
95
+ if (this.child && doesItShouldPreventChildValidation === false) return this.child.validate(errorsAsHashedSet, path, parseResult, options);
96
+ return parseResult;
97
+ }
98
+ /**
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.
101
+ *
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.
106
+ */ static createAndAppendFallback(schema, fallback, options) {
107
+ const schemaWithProtected = schema;
108
+ let validatorInstance = schemaWithProtected.__rootFallbacksValidator;
109
+ // eslint-disable-next-line ts/no-unnecessary-condition
110
+ if (schemaWithProtected.__rootFallbacksValidator === undefined) {
111
+ validatorInstance = new Validator(fallback.type);
112
+ schemaWithProtected.__rootFallbacksValidator = validatorInstance;
113
+ }
114
+ validatorInstance.addFallback(schema, fallback.type, fallback.callback, options);
115
+ return validatorInstance;
116
+ }
117
+ toString(ident = 0) {
118
+ return `Priority: ${this.priority}\nFallbacks: ${this.fallbacks.length}\n${this.child ? `Children:\n${this.child.toString(ident + 2)}` : ''}`;
119
+ }
120
+ }
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@palmares/schemas",
3
+ "version": "0.0.1",
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
+ "main": "./dist/cjs/src/index.js",
6
+ "module": "./dist/esm/src/index.js",
7
+ "types": "./dist/cjs/types/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/cjs/types/index.d.ts",
11
+ "node": "./dist/cjs/src/index.js",
12
+ "require": "./dist/cjs/src/index.js",
13
+ "import": "./dist/esm/src/index.js",
14
+ "default": "./dist/esm/src/index.js"
15
+ }
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/palmaresHQ/palmares.git"
20
+ },
21
+ "keywords": [
22
+ "palmares",
23
+ "schema",
24
+ "package"
25
+ ],
26
+ "type": "module",
27
+ "author": "Nicolas Melo",
28
+ "license": "MIT",
29
+ "bugs": {
30
+ "url": "https://github.com/palmaresHQ/palmares/issues"
31
+ },
32
+ "homepage": "https://github.com/palmaresHQ/palmares#readme",
33
+ "dependencies": {
34
+ "@palmares/databases": "0.0.2",
35
+ "@palmares/core": "0.0.4"
36
+ },
37
+ "scripts": {
38
+ "clear": "rimraf ./dist",
39
+ "build:types": "tsc --project tsconfig.types.json",
40
+ "build:cjs": "swc ./src -d ./dist/cjs --config-file ../../build/.commonjs.swcrc",
41
+ "build:module": "swc ./src -d ./dist/esm --config-file ../../build/.esm.swcrc",
42
+ "build": "pnpm run clear && pnpm run build:cjs && pnpm run build:module && pnpm run build:types",
43
+ "build:types:watch": "tsc --project tsconfig.types.json --watch --preserveWatchOutput",
44
+ "build:cjs:watch": "swc ./src -d ./dist/cjs --config-file ../../build/.commonjs.swcrc --watch",
45
+ "build:module:watch": "swc ./src -d ./dist/esm --config-file ../../build/.esm.swcrc --watch",
46
+ "build:watch": "pnpm run build:cjs:watch & pnpm run build:module:watch & pnpm run build:types:watch"
47
+ }
48
+ }
@@ -0,0 +1,31 @@
1
+ import FieldAdapter from '.';
2
+
3
+ import type WithFallback from '../../utils';
4
+ import type { NumberAdapterTranslateArgs } from '../types';
5
+
6
+ export function arrayFieldAdapter<
7
+ TTranslate extends ArrayFieldAdapter['translate'],
8
+ TToString extends ArrayFieldAdapter['toString'],
9
+ TFormatError extends ArrayFieldAdapter['formatError'],
10
+ TParse extends ArrayFieldAdapter['parse']
11
+ >(args: { translate: TTranslate; toString?: TToString; formatError?: TFormatError; parse?: TParse }) {
12
+ class CustomArrayFieldAdapter extends ArrayFieldAdapter {
13
+ translate = args.translate;
14
+ toString = args.toString as TToString;
15
+ formatError = args.formatError as TFormatError;
16
+ parse = args.parse as TParse;
17
+ }
18
+
19
+ return CustomArrayFieldAdapter as typeof ArrayFieldAdapter & {
20
+ new (): ArrayFieldAdapter & {
21
+ translate: TTranslate;
22
+ toString: TToString;
23
+ formatError: TFormatError;
24
+ parse: TParse;
25
+ };
26
+ };
27
+ }
28
+
29
+ export default class ArrayFieldAdapter extends FieldAdapter {
30
+ translate(_fieldAdapter: FieldAdapter, _args: NumberAdapterTranslateArgs): any | WithFallback<'array'> {}
31
+ }
@@ -0,0 +1,48 @@
1
+ import FieldAdapter from '.';
2
+ import { SchemaAdapterNotImplementedError } from '../../exceptions';
3
+
4
+ import type SchemaAdapter from '..';
5
+ import type WithFallback from '../../utils';
6
+ import type { BooleanAdapterTranslateArgs } from '../types';
7
+
8
+ export function booleanFieldAdapter<
9
+ TTranslate extends BooleanFieldAdapter['translate'],
10
+ TToString extends BooleanFieldAdapter['toString'],
11
+ TFormatError extends BooleanFieldAdapter['formatError'],
12
+ TParse extends BooleanFieldAdapter['parse']
13
+ >(args: {
14
+ translate: TTranslate;
15
+ toString?: TToString;
16
+ formatError?: TFormatError;
17
+ parse?: TParse;
18
+ }) {
19
+ class CustomBooleanFieldAdapter extends BooleanFieldAdapter {
20
+ translate = args.translate;
21
+ toString = args.toString as TToString;
22
+ formatError = args.formatError as TFormatError;
23
+ parse = args.parse as TParse;
24
+ }
25
+
26
+ return CustomBooleanFieldAdapter as typeof BooleanFieldAdapter & {
27
+ new (): BooleanFieldAdapter & {
28
+ translate: TTranslate;
29
+ toString: TToString;
30
+ formatError: TFormatError;
31
+ parse: TParse;
32
+ }
33
+ }
34
+ }
35
+
36
+ export default class BooleanFieldAdapter extends FieldAdapter {
37
+ translate(_fieldAdapter: FieldAdapter, _args: BooleanAdapterTranslateArgs): any | WithFallback<'boolean'> {}
38
+
39
+ parse(
40
+ _adapter: SchemaAdapter,
41
+ _fieldAdapter: FieldAdapter,
42
+ _result: any,
43
+ _value: any,
44
+ _args: BooleanAdapterTranslateArgs
45
+ ): Promise<{ errors: any; parsed: any }> {
46
+ throw new SchemaAdapterNotImplementedError({ className: this.constructor.name, functionName: 'parse' });
47
+ }
48
+ }
@@ -0,0 +1,49 @@
1
+ import FieldAdapter from '.';
2
+ import { SchemaAdapterNotImplementedError } from '../../exceptions';
3
+
4
+ import type SchemaAdapter from '..';
5
+ import type WithFallback from '../../utils';
6
+ import type { DatetimeAdapterTranslateArgs } from '../types';
7
+
8
+
9
+ export function datetimeFieldAdapter<
10
+ TTranslate extends DatetimeFieldAdapter['translate'],
11
+ TToString extends DatetimeFieldAdapter['toString'],
12
+ TFormatError extends DatetimeFieldAdapter['formatError'],
13
+ TParse extends DatetimeFieldAdapter['parse']
14
+ >(args: {
15
+ translate: TTranslate;
16
+ toString?: TToString;
17
+ formatError?: TFormatError;
18
+ parse?: TParse;
19
+ }) {
20
+ class CustomDatetimeFieldAdapter extends DatetimeFieldAdapter {
21
+ translate = args.translate;
22
+ toString = args.toString as TToString;
23
+ formatError = args.formatError as TFormatError;
24
+ parse = args.parse as TParse;
25
+ }
26
+
27
+ return CustomDatetimeFieldAdapter as typeof DatetimeFieldAdapter & {
28
+ new (): DatetimeFieldAdapter & {
29
+ translate: TTranslate;
30
+ toString: TToString;
31
+ formatError: TFormatError;
32
+ parse: TParse;
33
+ }
34
+ }
35
+ }
36
+
37
+ export default class DatetimeFieldAdapter extends FieldAdapter {
38
+ translate(_fieldAdapter: FieldAdapter, _args: DatetimeAdapterTranslateArgs): any | WithFallback<'datetime'> {}
39
+
40
+ parse(
41
+ _adapter: SchemaAdapter,
42
+ _fieldAdapter: FieldAdapter,
43
+ _result: any,
44
+ _value: any,
45
+ _args: DatetimeAdapterTranslateArgs
46
+ ): Promise<{ errors: any; parsed: any }> {
47
+ throw new SchemaAdapterNotImplementedError({ className: this.constructor.name, functionName: 'parse' });
48
+ }
49
+ }
@@ -0,0 +1,72 @@
1
+ import { SchemaAdapterNotImplementedError } from '../../exceptions';
2
+
3
+ import type { SupportedSchemas } from '../../types';
4
+ import type WithFallback from '../../utils';
5
+ import type SchemaAdapter from '../index';
6
+ import type { AdapterToStringArgs, AdapterTranslateArgs, ErrorCodes } from '../types';
7
+
8
+ export function fieldAdapter<
9
+ TTranslate extends FieldAdapter['translate'],
10
+ TToString extends FieldAdapter['toString'],
11
+ TFormatError extends FieldAdapter['formatError'],
12
+ TParse extends FieldAdapter['parse']
13
+ >(args: {
14
+ translate: TTranslate;
15
+ toString?: TToString;
16
+ formatError?: TFormatError;
17
+ parse?: TParse;
18
+ }) {
19
+ class CustomFieldAdapter extends FieldAdapter {
20
+ translate = args.translate;
21
+ toString = args.toString as TToString;
22
+ formatError = args.formatError as TFormatError;
23
+ parse = args.parse as TParse;
24
+ }
25
+
26
+ return CustomFieldAdapter as typeof FieldAdapter & {
27
+ new (): FieldAdapter & {
28
+ translate: TTranslate;
29
+ toString: TToString;
30
+ formatError: TFormatError;
31
+ parse: TParse;
32
+ }
33
+ }
34
+ }
35
+ export default class FieldAdapter {
36
+ translate(_fieldAdapter: FieldAdapter, _args: AdapterTranslateArgs<SupportedSchemas>, _base?: any): any | WithFallback<SupportedSchemas> {
37
+ throw new SchemaAdapterNotImplementedError({ className: this.constructor.name, functionName: 'translate' });
38
+ }
39
+
40
+ parse(
41
+ _adapter: SchemaAdapter,
42
+ _fieldAdapter: FieldAdapter,
43
+ _result: any,
44
+ _value: any,
45
+ _args: Omit<AdapterTranslateArgs<SupportedSchemas>, 'withFallback'>,
46
+ ): Promise<{ errors: any; parsed: any }> {
47
+ throw new SchemaAdapterNotImplementedError({ className: this.constructor.name, functionName: 'parse' });
48
+ }
49
+
50
+ toString(
51
+ _adapter: SchemaAdapter,
52
+ _fieldAdapter: FieldAdapter,
53
+ _args: AdapterToStringArgs,
54
+ _base?: any
55
+ ): Promise<string> {
56
+ throw new SchemaAdapterNotImplementedError({ className: this.constructor.name, functionName: 'toString' });
57
+ }
58
+
59
+ // eslint-disable-next-line ts/require-await
60
+ async formatError(
61
+ _adapter: SchemaAdapter,
62
+ _fieldAdapter: FieldAdapter,
63
+ _error: any,
64
+ _metadata?: any
65
+ ): Promise<{
66
+ message: string;
67
+ path: (string | number)[];
68
+ code: ErrorCodes;
69
+ }> {
70
+ throw new SchemaAdapterNotImplementedError({ className: this.constructor.name, functionName: 'formatError' });
71
+ }
72
+ }
@@ -0,0 +1,49 @@
1
+ import FieldAdapter from '.';
2
+ import { SchemaAdapterNotImplementedError } from '../../exceptions';
3
+
4
+ import type SchemaAdapter from '..';
5
+ import type WithFallback from '../../utils';
6
+ import type { NumberAdapterTranslateArgs } from '../types';
7
+
8
+
9
+ export function numberFieldAdapter<
10
+ TTranslate extends NumberFieldAdapter['translate'],
11
+ TToString extends NumberFieldAdapter['toString'],
12
+ TFormatError extends NumberFieldAdapter['formatError'],
13
+ TParse extends NumberFieldAdapter['parse']
14
+ >(args: {
15
+ translate: TTranslate;
16
+ toString?: TToString;
17
+ formatError?: TFormatError;
18
+ parse?: TParse;
19
+ }) {
20
+ class CustomNumberFieldAdapter extends NumberFieldAdapter {
21
+ translate = args.translate;
22
+ toString = args.toString as TToString;
23
+ formatError = args.formatError as TFormatError;
24
+ parse = args.parse as TParse;
25
+ }
26
+
27
+ return CustomNumberFieldAdapter as typeof NumberFieldAdapter & {
28
+ new (): NumberFieldAdapter & {
29
+ translate: TTranslate;
30
+ toString: TToString;
31
+ formatError: TFormatError;
32
+ parse: TParse;
33
+ }
34
+ }
35
+ }
36
+
37
+ export default class NumberFieldAdapter extends FieldAdapter {
38
+ translate(_fieldAdapter: FieldAdapter, _args: NumberAdapterTranslateArgs): any | WithFallback<'number'> {}
39
+
40
+ parse(
41
+ _adapter: SchemaAdapter,
42
+ _fieldAdapter: FieldAdapter,
43
+ _result: any,
44
+ _value: any,
45
+ _args: NumberAdapterTranslateArgs
46
+ ): Promise<{ errors: any; parsed: any }> {
47
+ throw new SchemaAdapterNotImplementedError({ className: this.constructor.name, functionName: 'parse' });
48
+ }
49
+ }