@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,16 +1,19 @@
1
1
  import Schema from './schema';
2
- import { getDefaultAdapter } from '../conf';
3
2
  import { defaultTransform, defaultTransformToAdapter, transformSchemaAndCheckIfShouldBeHandledByFallbackOnComplexSchemas } from '../utils';
4
3
  import { unionValidation } from '../validators/union';
5
4
  import Validator from '../validators/utils';
6
5
  export default class UnionSchema extends Schema {
6
+ __type = {
7
+ message: 'Invalid type',
8
+ check: (value)=>Array.from(this.__schemas).some((schema)=>schema['__type'].check(value))
9
+ };
7
10
  __schemas = new Set();
8
11
  constructor(schemas){
9
12
  super();
10
13
  this.__schemas = new Set(schemas);
11
14
  }
12
- async _transformToAdapter(options) {
13
- return await defaultTransformToAdapter(async (adapter)=>{
15
+ async __transformToAdapter(options) {
16
+ return defaultTransformToAdapter(async (adapter)=>{
14
17
  const promises = [];
15
18
  const shouldBeHighPriorityFallback = adapter.union === undefined;
16
19
  const transformedSchemasAsString = [];
@@ -36,6 +39,7 @@ export default class UnionSchema extends Schema {
36
39
  await Promise.all(promises);
37
40
  return defaultTransform('union', this, adapter, adapter.union, (isStringVersion)=>({
38
41
  nullable: this.__nullable,
42
+ type: this.__type,
39
43
  optional: this.__optional,
40
44
  schemas: isStringVersion ? transformedSchemasAsString : transformedSchemas,
41
45
  parsers: {
@@ -45,12 +49,12 @@ export default class UnionSchema extends Schema {
45
49
  }), {}, {
46
50
  shouldAddStringVersion: options.shouldAddStringVersion,
47
51
  fallbackIfNotSupported: async ()=>{
48
- if (options.appendFallbacksBeforeAdapterValidation) options.appendFallbacksBeforeAdapterValidation('union', async (adapter, fieldAdapter, schema, translatedSchemas, value, path, options)=>{
52
+ if (options.appendFallbacksBeforeAdapterValidation) options.appendFallbacksBeforeAdapterValidation(this, 'union', async (adapter, fieldAdapter, schema, translatedSchemas, value, path, options)=>{
49
53
  const parsedValues = {
50
54
  parsed: value,
51
55
  errors: []
52
56
  };
53
- // const initialErrorsAsHashedSet = new Set(Array.from(options.errorsAsHashedSet || []));
57
+ // const initialErrorsAsHashedSet = new Set(Array.from(options.errorsAsHashedSet || []));
54
58
  for (const translatedSchema of translatedSchemas){
55
59
  //options.errorsAsHashedSet = initialErrorsAsHashedSet;
56
60
  const { parsed, errors } = await schema.__validateByAdapter(adapter, fieldAdapter, translatedSchema, value, path, options);
@@ -69,14 +73,14 @@ export default class UnionSchema extends Schema {
69
73
  });
70
74
  const transformedSchemasAsPromises = [];
71
75
  for (const schema of this.__schemas)transformedSchemasAsPromises.push(schema.__transformToAdapter(options));
72
- console.log((await Promise.all(transformedSchemasAsPromises)).flat());
73
76
  return (await Promise.all(transformedSchemasAsPromises)).flat();
74
77
  }
75
78
  });
76
- }, this.__transformedSchemas, options, 'union');
79
+ }, this, this.__transformedSchemas, options, 'union');
77
80
  }
78
81
  /**
79
- * This let's you refine the schema with custom validations. This is useful when you want to validate something that is not supported by default by the schema adapter.
82
+ * This let's you refine the schema with custom validations. This is useful when you want to validate something that
83
+ * is not supported by default by the schema adapter.
80
84
  *
81
85
  * @example
82
86
  * ```typescript
@@ -88,7 +92,8 @@ export default class UnionSchema extends Schema {
88
92
  *
89
93
  * const { errors, parsed } = await numberSchema.parse(-1);
90
94
  *
91
- * console.log(errors); // [{ isValid: false, code: 'invalid_number', message: 'The number should be greater than 0', path: [] }]
95
+ * // [{ isValid: false, code: 'invalid_number', message: 'The number should be greater than 0', path: [] }]
96
+ * console.log(errors);
92
97
  * ```
93
98
  *
94
99
  * @param refinementCallback - The callback that will be called to validate the value.
@@ -124,8 +129,25 @@ export default class UnionSchema extends Schema {
124
129
  return super.optional(options);
125
130
  }
126
131
  /**
127
- * Allows the value to be null and ONLY null. You can also use this function to set a custom message when the value is NULL by setting
128
- * the { message: 'Your custom message', allow: false } on the options.
132
+ * Just adds a message when the value is undefined. It's just a syntax sugar for
133
+ *
134
+ * ```typescript
135
+ * p.string().optional({ message: 'This value cannot be null', allow: false })
136
+ * ```
137
+ *
138
+ * @param options - The options of nonOptional function
139
+ * @param options.message - A custom message if the value is undefined.
140
+ *
141
+ * @returns - The schema.
142
+ */ nonOptional(options) {
143
+ return super.optional({
144
+ message: options?.message,
145
+ allow: false
146
+ });
147
+ }
148
+ /**
149
+ * Allows the value to be null and ONLY null. You can also use this function to set a custom message when the value
150
+ * is NULL by setting the { message: 'Your custom message', allow: false } on the options.
129
151
  *
130
152
  * @example
131
153
  * ```typescript
@@ -151,14 +173,33 @@ export default class UnionSchema extends Schema {
151
173
  return super.nullable(options);
152
174
  }
153
175
  /**
154
- * This method will remove the value from the representation of the schema. If the value is undefined it will keep that way
176
+ * Just adds a message when the value is null. It's just a syntax sugar for
177
+ *
178
+ * ```typescript
179
+ * p.string().nullable({ message: 'This value cannot be null', allow: false })
180
+ * ```
181
+ *
182
+ * @param options - The options of nonNullable function
183
+ * @param options.message - A custom message if the value is null.
184
+ *
185
+ * @returns - The schema.
186
+ */ nonNullable(options) {
187
+ return super.nullable({
188
+ message: options?.message || '',
189
+ allow: false
190
+ });
191
+ }
192
+ /**
193
+ * This method will remove the value from the representation of the schema. If the value is undefined it will keep
194
+ * that way
155
195
  * otherwise it will set the value to undefined after it's validated.
156
196
  * This is used in conjunction with the {@link data} function, the {@link parse} function or {@link validate}
157
197
  * function. This will remove the value from the representation of the schema.
158
198
  *
159
- * By default, the value will be removed just from the representation, in other words, when you call the {@link data} function.
160
- * But if you want to remove the value from the internal representation, you can pass the argument `toInternal` as true.
161
- * Then if you still want to remove the value from the representation, you will need to pass the argument `toRepresentation` as true as well.
199
+ * By default, the value will be removed just from the representation, in other words, when you call the {@link data}
200
+ * function. But if you want to remove the value from the internal representation, you can pass the argument
201
+ * `toInternal` as true. Then if you still want to remove the value from the representation, you will need to pass
202
+ * the argument `toRepresentation` as true as well.
162
203
  *
163
204
  * @example
164
205
  * ```typescript
@@ -180,18 +221,19 @@ export default class UnionSchema extends Schema {
180
221
  * ```
181
222
  *
182
223
  *
183
- * @param args - By default, the value will be removed just from the representation, in other words, when you call the {@link data} function.
184
- * But if you want to remove the value from the internal representation, you can pass the argument `toInternal` as true.
185
- * Then if you still want to remove the value from the representation, you will need to pass the argument `toRepresentation` as true as well.
224
+ * @param args - By default, the value will be removed just from the representation, in other words, when you call
225
+ * the {@link data} function. But if you want to remove the value from the internal representation, you can pass
226
+ * the argument `toInternal` as true. Then if you still want to remove the value from the representation, you
227
+ * will need to pass the argument `toRepresentation` as true as well.
186
228
  *
187
229
  * @returns The schema.
188
230
  */ omit(args) {
189
231
  return super.omit(args);
190
232
  }
191
233
  /**
192
- * This function is used in conjunction with the {@link validate} function. It's used to save a value to an external source
193
- * like a database. You should always return the schema after you save the value, that way we will always have the correct type
194
- * of the schema after the save operation.
234
+ * This function is used in conjunction with the {@link validate} function. It's used to save a value to an external
235
+ * source like a database. You should always return the schema after you save the value, that way we will always
236
+ * have the correct type of the schema after the save operation.
195
237
  *
196
238
  * You can use the {@link toRepresentation} function to transform and clean the value it returns after the save.
197
239
  *
@@ -233,7 +275,8 @@ export default class UnionSchema extends Schema {
233
275
  return super.onSave(callback);
234
276
  }
235
277
  /**
236
- * This function is used to add a default value to the schema. If the value is either undefined or null, the default value will be used.
278
+ * This function is used to add a default value to the schema. If the value is either undefined or null, the default
279
+ * value will be used.
237
280
  *
238
281
  * @example
239
282
  * ```typescript
@@ -249,8 +292,47 @@ export default class UnionSchema extends Schema {
249
292
  return super.default(defaultValueOrFunction);
250
293
  }
251
294
  /**
252
- * This function let's you customize the schema your own way. After we translate the schema on the adapter we call this function to let you customize
253
- * the custom schema your own way. Our API does not support passthrough? No problem, you can use this function to customize the zod schema.
295
+ * This function is used to transform the value to the representation without validating it.
296
+ * This is useful when you want to return a data from a query directly to the user. But for example
297
+ * you are returning the data of a user, you can clean the password or any other sensitive data.
298
+ *
299
+ * @example
300
+ * ```typescript
301
+ * import * as p from '@palmares/schemas';
302
+ *
303
+ * const userSchema = p.object({
304
+ * id: p.number().optional(),
305
+ * name: p.string(),
306
+ * email: p.string().email(),
307
+ * password: p.string().optional()
308
+ * }).toRepresentation(async (value) => {
309
+ * return {
310
+ * id: value.id,
311
+ * name: value.name,
312
+ * email: value.email
313
+ * }
314
+ * });
315
+ *
316
+ * const user = await userSchema.data({
317
+ * id: 1,
318
+ * name: 'John Doe',
319
+ * email: 'john@gmail.com',
320
+ * password: '123456'
321
+ * });
322
+ * ```
323
+ */ async data(value) {
324
+ const parsedValue = await super.data(value);
325
+ for (const schema of Array.from(this.__schemas)){
326
+ if (schema['__optional'].allow && value === undefined) return schema.data(parsedValue);
327
+ if (schema['__nullable'].allow && value === null) return schema.data(parsedValue);
328
+ if (schema['__type'].check(parsedValue)) return schema.data(parsedValue);
329
+ }
330
+ return parsedValue;
331
+ }
332
+ /**
333
+ * This function let's you customize the schema your own way. After we translate the schema on the adapter we call
334
+ * this function to let you customize the custom schema your own way. Our API does not support passthrough?
335
+ * No problem, you can use this function to customize the zod schema.
254
336
  *
255
337
  * @example
256
338
  * ```typescript
@@ -262,21 +344,22 @@ export default class UnionSchema extends Schema {
262
344
  *
263
345
  * const { errors, parsed } = await numberSchema.parse(-1);
264
346
  *
265
- * console.log(errors); // [{ isValid: false, code: 'nonnegative', message: 'The number should be nonnegative', path: [] }]
347
+ * // [{ isValid: false, code: 'nonnegative', message: 'The number should be nonnegative', path: [] }]
348
+ * console.log(errors);
266
349
  * ```
267
350
  *
268
351
  * @param callback - The callback that will be called to customize the schema.
269
- * @param toStringCallback - The callback that will be called to transform the schema to a string when you want to compile the underlying schema
270
- * to a string so you can save it for future runs.
352
+ * @param toStringCallback - The callback that will be called to transform the schema to a string when you want
353
+ * to compile the underlying schema to a string so you can save it for future runs.
271
354
  *
272
355
  * @returns The schema.
273
356
  */ extends(callback, toStringCallback) {
274
357
  return super.extends(callback, toStringCallback);
275
358
  }
276
359
  /**
277
- * This function is used to transform the value to the representation of the schema. When using the {@link data} function. With this function you have full
278
- * control to add data cleaning for example, transforming the data and whatever. Another use case is when you want to return deeply nested recursive data.
279
- * The schema maps to itself.
360
+ * This function is used to transform the value to the representation of the schema. When using the {@link data}
361
+ * function. With this function you have full control to add data cleaning for example, transforming the data and
362
+ * whatever. Another use case is when you want to return deeply nested recursive data. The schema maps to itself.
280
363
  *
281
364
  * @example
282
365
  * ```typescript
@@ -319,8 +402,9 @@ export default class UnionSchema extends Schema {
319
402
  return super.toRepresentation(toRepresentationCallback);
320
403
  }
321
404
  /**
322
- * This function is used to transform the value to the internal representation of the schema. This is useful when you want to transform the value
323
- * to a type that the schema adapter can understand. For example, you might want to transform a string to a date. This is the function you use.
405
+ * This function is used to transform the value to the internal representation of the schema. This is useful when you
406
+ * want to transform the value to a type that the schema adapter can understand. For example, you might want to
407
+ * transform a string to a date. This is the function you use.
324
408
  *
325
409
  * @example
326
410
  * ```typescript
@@ -353,8 +437,9 @@ export default class UnionSchema extends Schema {
353
437
  return super.toInternal(toInternalCallback);
354
438
  }
355
439
  /**
356
- * Called before the validation of the schema. Let's say that you want to validate a date that might receive a string, you can convert that string to a date
357
- * here BEFORE the validation. This pretty much transforms the value to a type that the schema adapter can understand.
440
+ * Called before the validation of the schema. Let's say that you want to validate a date that might receive a string,
441
+ * you can convert that string to a date here BEFORE the validation. This pretty much transforms the value to a type
442
+ * that the schema adapter can understand.
358
443
  *
359
444
  * @example
360
445
  * ```
@@ -376,12 +461,6 @@ export default class UnionSchema extends Schema {
376
461
  }
377
462
  static new(schemas) {
378
463
  const returnValue = new UnionSchema(schemas);
379
- const adapterInstance = getDefaultAdapter();
380
- returnValue.__transformedSchemas[adapterInstance.constructor.name] = {
381
- transformed: false,
382
- adapter: adapterInstance,
383
- schemas: []
384
- };
385
464
  return returnValue;
386
465
  }
387
466
  }
@@ -1 +1,14 @@
1
- export { };
1
+ /**
2
+ * Retrieve the typescript type of a schema.
3
+ *
4
+ * First generic is `typeof myCustomSchema`.
5
+ *
6
+ * Second generic is:
7
+ * - 'input' - The data passed to `.parse` and `.validate` functions. Defaults to this.
8
+ * - 'output' - (use `'representation'` to get the data format you are
9
+ * passing to the user) The data passed to `.data` function to return to the
10
+ * user.
11
+ * - 'representation' - The data after `toRepresentation`, usually, use this over 'output'
12
+ * - 'internal' - The data after it's transformed for the `toSave` callback.
13
+ * - 'validate' - The data for `toValidate` callback.
14
+ */ export { };
@@ -1,8 +1,11 @@
1
+ import SchemaAdapter from './adapter';
2
+ import { getDefaultAdapter } from './conf';
1
3
  import { checkType, nullable, optional } from './validators/schema';
2
4
  import Validator from './validators/utils';
3
5
  /**
4
- * The usage of this is that imagine that the library doesn't support a specific feature that we support on our schema definition, it can return an instance
5
- * of this class and with this instance we are able to fallback to our default implementation of the schema validation.
6
+ * The usage of this is that imagine that the library doesn't support a specific feature that we support on
7
+ * our schema definition, it can return an instance of this class and with this instance we are able to
8
+ * fallback to our default implementation of the schema validation.
6
9
  */ export default class WithFallback {
7
10
  fallbackFor;
8
11
  transformedSchema;
@@ -14,8 +17,9 @@ import Validator from './validators/utils';
14
17
  }
15
18
  }
16
19
  /**
17
- * Factory function for creating a new instance of WithFallback. We call that function when parsing the schema adapter, and then, inside of the adapter the user will can the inner function
18
- * to create a new instance of WithFallback.
20
+ * Factory function for creating a new instance of WithFallback. We call that function when parsing the
21
+ * schema adapter, and then, inside of the adapter the user will can the inner function to create a new
22
+ * instance of WithFallback.
19
23
  *
20
24
  * @param adapterType - The type of the adapter that we are using.
21
25
  *
@@ -33,18 +37,22 @@ export function parseErrorsFactory(schemaAdapter) {
33
37
  };
34
38
  }
35
39
  /**
36
- * The default transform function that we use for the schema adapters. This function tries to abstract away the complexity of translating the schema to the adapter.
40
+ * The default transform function that we use for the schema adapters. This function tries to abstract away
41
+ * the complexity of translating the schema to the adapter.
37
42
  *
38
- * So first things first, WHAT IS a fallback? A fallback is a function that we call when the user defines a validation that is not supported by the adapter. For example, imagine that
39
- * for some reason the adapter doesn't support the `max` validation, we can define a fallback for that validation and then, when the user defines that validation, we call the fallback
40
- * function. So, even if the adapter doesn't support that validation our schema will still be able to validate that.
43
+ * So first things first, WHAT IS a fallback? A fallback is a function that we call when the user defines a
44
+ * validation that is not supported by the adapter. For example, imagine that for some reason the adapter
45
+ * doesn't support the `max` validation, we can define a fallback for that validation and then, when the
46
+ * user defines that validation, we call the fallback function. So, even if the adapter doesn't support that
47
+ * validation our schema will still be able to validate that.
41
48
  *
42
- * @param type - The type of the adapter that we are using, can be a number, an object, all of the possible schema adapters.
49
+ * @param type - The type of the adapter that we are using, can be a number, an object, all of the possible
50
+ * schema adapters.
43
51
  * @param schema - The schema that we are translating.
44
- * @param validationData - The data that we are using to validate the schema. This means for example, the `max` validation, the `min` validation, etc. The message of the validation when
45
- * it is not valid, etc.
46
- * @param fallbackFunctions - The fallback functions that we are using to validate the schema. Those are the functions we fallback to when the user defines a validation that is not
47
- * supported by the adapter.
52
+ * @param validationData - The data that we are using to validate the schema. This means for example, the
53
+ * `max` validation, the `min` validation, etc. The message of the validation when it is not valid, etc.
54
+ * @param fallbackFunctions - The fallback functions that we are using to validate the schema. Those are
55
+ * the functions we fallback to when the user defines a validation that is not supported by the adapter.
48
56
  *
49
57
  * @returns - The translated schema for something that the adapter is able to understand.
50
58
  */ export async function defaultTransform(type, schema, adapter, fieldAdapter, getValidationData, fallbackFunctions, options) {
@@ -78,19 +86,22 @@ export function parseErrorsFactory(schemaAdapter) {
78
86
  for (const fallback of validatorsIfFallbackOrNotSupported)Validator.createAndAppendFallback(schema, fallback);
79
87
  }
80
88
  };
81
- const hasFallbacks = schemaWithPrivateFields.__rootFallbacksValidator instanceof Validator;
89
+ const appendRequiredFallbacks = ()=>{
90
+ const hasFallbacks = schemaWithPrivateFields.__rootFallbacksValidator instanceof Validator;
91
+ if (hasFallbacks) {
92
+ Validator.createAndAppendFallback(schema, optional(schemaWithPrivateFields.__optional));
93
+ Validator.createAndAppendFallback(schema, nullable(schemaWithPrivateFields.__nullable));
94
+ Validator.createAndAppendFallback(schema, checkType(schemaWithPrivateFields.__type));
95
+ }
96
+ };
82
97
  const isFieldAdapterNotSupportedForThatFieldType = fieldAdapter === undefined;
83
- if (hasFallbacks) {
84
- Validator.createAndAppendFallback(schema, optional(schemaWithPrivateFields.__optional));
85
- Validator.createAndAppendFallback(schema, nullable(schemaWithPrivateFields.__nullable));
86
- Validator.createAndAppendFallback(schema, checkType(schemaWithPrivateFields.__type));
87
- }
88
98
  if (options.fallbackIfNotSupported !== undefined && isFieldAdapterNotSupportedForThatFieldType) {
89
99
  const existingFallbacks = Object.keys(fallbackFunctions);
90
100
  const allParsers = Object.keys(validationData['parsers']);
91
101
  appendRootFallback();
92
102
  for (const fallback of existingFallbacks)checkIfShouldAppendFallbackAndAppend(fallback);
93
103
  for (const parser of allParsers)checkIfShouldUseParserAndAppend(parser);
104
+ appendRequiredFallbacks();
94
105
  return options.fallbackIfNotSupported();
95
106
  }
96
107
  if (!fieldAdapter) throw new Error('The field adapter is not supported and no fallback was provided.');
@@ -107,6 +118,7 @@ export function parseErrorsFactory(schemaAdapter) {
107
118
  checkIfShouldUseParserAndAppend(fallback);
108
119
  }
109
120
  const [extendedOrNotSchema, extendedOrNotSchemaString] = getExtendedOrNotSchemaAndString(translatedSchemaOrWithFallback.transformedSchema, stringVersion);
121
+ appendRequiredFallbacks();
110
122
  return [
111
123
  {
112
124
  transformed: extendedOrNotSchema,
@@ -123,9 +135,18 @@ export function parseErrorsFactory(schemaAdapter) {
123
135
  ];
124
136
  }
125
137
  /**
126
- * This function is used to transform the schema to the adapter. By default it caches the transformed schemas on the schema instance. So on subsequent validations we don't need
127
- * to transform to the schema again.
128
- */ export async function defaultTransformToAdapter(callback, transformedSchemas, options, type) {
138
+ * This function is used to transform the schema to the adapter. By default it caches the transformed schemas on
139
+ * the schema instance. So on subsequent validations we don't need to transform to the schema again.
140
+ */ export async function defaultTransformToAdapter(callback, schema, transformedSchemas, options, type) {
141
+ const isTransformedSchemasEmpty = Object.keys(transformedSchemas).length <= 0;
142
+ if (isTransformedSchemasEmpty) {
143
+ const adapterInstanceToUse = options.schemaAdapter instanceof SchemaAdapter ? options.schemaAdapter : getDefaultAdapter();
144
+ schema['__transformedSchemas'][adapterInstanceToUse.constructor.name] = {
145
+ transformed: false,
146
+ adapter: adapterInstanceToUse,
147
+ schemas: []
148
+ };
149
+ }
129
150
  const schemaAdapterNameToUse = options.schemaAdapter?.constructor.name || Object.keys(transformedSchemas)[0];
130
151
  const isACustomSchemaAdapterAndNotYetDefined = // eslint-disable-next-line ts/no-unnecessary-condition
131
152
  transformedSchemas[schemaAdapterNameToUse] === undefined && options.schemaAdapter !== undefined;
@@ -143,22 +164,27 @@ export function parseErrorsFactory(schemaAdapter) {
143
164
  transformedSchemas[schemaAdapterNameToUse].transformed = true;
144
165
  return transformedSchemas[schemaAdapterNameToUse].schemas;
145
166
  }
146
- export async function formatErrorFromParseMethod(adapter, fieldAdapter, error, path, errorsAsHashedSet) {
147
- const formattedError = await fieldAdapter.formatError(adapter, fieldAdapter, error);
167
+ export async function formatErrorFromParseMethod(adapter, fieldAdapter, error, received, schema, path, errorsAsHashedSet) {
168
+ const formattedError = await fieldAdapter.formatError(adapter, adapter.field, schema, error);
148
169
  formattedError.path = Array.isArray(formattedError.path) ? [
149
170
  ...path,
150
171
  ...formattedError.path
151
172
  ] : path;
152
173
  const formattedErrorAsParseResultError = formattedError;
153
174
  formattedErrorAsParseResultError.isValid = false;
154
- errorsAsHashedSet.add(JSON.stringify(formattedErrorAsParseResultError));
175
+ const sortedError = Object.fromEntries(Object.entries(formattedErrorAsParseResultError).sort(([a], [b])=>a.localeCompare(b)));
176
+ const hashedError = JSON.stringify(sortedError);
177
+ errorsAsHashedSet.add(JSON.stringify(sortedError));
178
+ formattedErrorAsParseResultError.received = received;
155
179
  return formattedErrorAsParseResultError;
156
180
  }
157
181
  /**
158
- * Transform the schema and check if we should add a fallback validation for that schema. This is used for complex schemas like Objects, arrays, unions, etc.
182
+ * Transform the schema and check if we should add a fallback validation for that schema. This is used for complex
183
+ * schemas like Objects, arrays, unions, etc.
159
184
  */ export async function transformSchemaAndCheckIfShouldBeHandledByFallbackOnComplexSchemas(schema, options) {
160
185
  const schemaWithProtected = schema;
161
- const transformedData = await schemaWithProtected.__transformToAdapter(options); // This should come first because we will get the fallbacks of the field here.
186
+ // This should come first because we will get the fallbacks of the field here.
187
+ const transformedData = await schemaWithProtected.__transformToAdapter(options);
162
188
  // eslint-disable-next-line ts/no-unnecessary-condition
163
189
  const doesKeyHaveFallback = schemaWithProtected.__rootFallbacksValidator !== undefined;
164
190
  const doesKeyHaveToInternal = typeof schemaWithProtected.__toInternal === 'function';
@@ -173,3 +199,6 @@ export async function formatErrorFromParseMethod(adapter, fieldAdapter, error, p
173
199
  shouldAddFallbackValidation
174
200
  ];
175
201
  }
202
+ export function shouldRunDataOnComplexSchemas(schema) {
203
+ return typeof schema['__parsersToTransformValue'] === 'function' || typeof schema['__runBeforeParseAndData'] === 'function' || typeof schema['__toRepresentation'] === 'function' || typeof schema['__defaultFunction'] === 'function';
204
+ }
@@ -1,5 +1,6 @@
1
1
  export function arrayValidation(isTuple, schemas) {
2
2
  return {
3
+ name: 'array',
3
4
  type: 'medium',
4
5
  callback: async (value, path, options)=>{
5
6
  const isNotAnArray = Array.isArray(value) === false;
@@ -30,7 +31,8 @@ export function arrayValidation(isTuple, schemas) {
30
31
  ]
31
32
  };
32
33
  const errorsOfArray = [];
33
- // To speed things up, we can do a simple type check, if the value is of type number and number is on index 1, and on index 0 is a string,
34
+ // To speed things up, we can do a simple type check, if the value is of type number and
35
+ // number is on index 1, and on index 0 is a string,
34
36
  // if the value is a number we can skip checking at index 0.
35
37
  const schemaIndexByTypeof = new Map();
36
38
  let parsedValues = [];
@@ -72,6 +74,7 @@ export function arrayValidation(isTuple, schemas) {
72
74
  }
73
75
  export function minLength(args) {
74
76
  return {
77
+ name: 'minLength',
75
78
  type: 'low',
76
79
  // eslint-disable-next-line ts/require-await
77
80
  callback: async (value, path, _options)=>{
@@ -93,6 +96,7 @@ export function minLength(args) {
93
96
  }
94
97
  export function maxLength(args) {
95
98
  return {
99
+ name: 'maxLength',
96
100
  type: 'low',
97
101
  // eslint-disable-next-line ts/require-await
98
102
  callback: async (value, path, _options)=>{
@@ -114,6 +118,7 @@ export function maxLength(args) {
114
118
  }
115
119
  export function nonEmpty(args) {
116
120
  return {
121
+ name: 'nonEmpty',
117
122
  type: 'low',
118
123
  // eslint-disable-next-line ts/require-await
119
124
  callback: async (value, path, _options)=>{
@@ -1,5 +1,6 @@
1
1
  export function booleanValidation() {
2
2
  return {
3
+ name: 'boolean',
3
4
  type: 'medium',
4
5
  // eslint-disable-next-line ts/require-await
5
6
  callback: async (value, path, _options)=>{
@@ -22,6 +23,7 @@ export function booleanValidation() {
22
23
  }
23
24
  export function allowStringParser() {
24
25
  return {
26
+ name: 'allowString',
25
27
  type: 'high',
26
28
  // eslint-disable-next-line ts/require-await
27
29
  callback: async (value, _path, _options)=>{
@@ -1,5 +1,6 @@
1
1
  export function datetimeValidation() {
2
2
  return {
3
+ name: 'datetime',
3
4
  type: 'medium',
4
5
  // eslint-disable-next-line ts/require-await
5
6
  callback: async (value, path, _options)=>{
@@ -22,6 +23,7 @@ export function datetimeValidation() {
22
23
  }
23
24
  export function allowStringParser() {
24
25
  return {
26
+ name: 'allowString',
25
27
  type: 'high',
26
28
  // eslint-disable-next-line ts/require-await
27
29
  callback: async (value, _path, _options)=>{
@@ -43,6 +45,7 @@ export function allowStringParser() {
43
45
  }
44
46
  export function below(args) {
45
47
  return {
48
+ name: 'below',
46
49
  type: 'low',
47
50
  // eslint-disable-next-line ts/require-await
48
51
  callback: async (value, path, _options)=>{
@@ -64,6 +67,7 @@ export function below(args) {
64
67
  }
65
68
  export function above(args) {
66
69
  return {
70
+ name: 'above',
67
71
  type: 'low',
68
72
  // eslint-disable-next-line ts/require-await
69
73
  callback: async (value, path, _options)=>{
@@ -1,5 +1,6 @@
1
1
  export function numberValidation() {
2
2
  return {
3
+ name: 'number',
3
4
  type: 'medium',
4
5
  // eslint-disable-next-line ts/require-await
5
6
  callback: async (value, path, _options)=>{
@@ -20,6 +21,7 @@ export function numberValidation() {
20
21
  }
21
22
  export function max(args) {
22
23
  return {
24
+ name: 'max',
23
25
  type: 'low',
24
26
  // eslint-disable-next-line ts/require-await
25
27
  callback: async (value, path, _options)=>{
@@ -52,6 +54,7 @@ export function max(args) {
52
54
  }
53
55
  export function min(args) {
54
56
  return {
57
+ name: 'min',
55
58
  type: 'low',
56
59
  // eslint-disable-next-line ts/require-await
57
60
  callback: async (value, path)=>{
@@ -80,39 +83,20 @@ export function min(args) {
80
83
  }
81
84
  };
82
85
  }
83
- export function negative(args) {
86
+ export function integer(args) {
84
87
  return {
88
+ name: 'integer',
85
89
  type: 'low',
86
90
  // eslint-disable-next-line ts/require-await
87
91
  callback: async (value, path)=>{
88
- const isValid = args.allowZero ? value < 0 : value <= 0;
92
+ const isValid = Number.isInteger(value);
89
93
  return {
90
94
  parsed: value,
91
95
  errors: isValid ? [] : [
92
96
  {
93
97
  isValid: isValid,
94
98
  message: args.message,
95
- code: 'negative',
96
- path: path || []
97
- }
98
- ]
99
- };
100
- }
101
- };
102
- }
103
- export function positive(args) {
104
- return {
105
- type: 'low',
106
- // eslint-disable-next-line ts/require-await
107
- callback: async (value, path)=>{
108
- const isValid = args.allowZero ? value > 0 : value >= 0;
109
- return {
110
- parsed: value,
111
- errors: isValid ? [] : [
112
- {
113
- isValid: isValid,
114
- message: args.message,
115
- code: 'positive',
99
+ code: 'integer',
116
100
  path: path || []
117
101
  }
118
102
  ]
@@ -122,6 +106,7 @@ export function positive(args) {
122
106
  }
123
107
  export function maxDigits(args) {
124
108
  return {
109
+ name: 'maxDigits',
125
110
  type: 'low',
126
111
  // eslint-disable-next-line ts/require-await
127
112
  callback: async (value, path)=>{
@@ -142,6 +127,7 @@ export function maxDigits(args) {
142
127
  }
143
128
  export function decimalPlaces(args) {
144
129
  return {
130
+ name: 'decimalPlaces',
145
131
  type: 'low',
146
132
  // eslint-disable-next-line ts/require-await
147
133
  callback: async (value, path)=>{
@@ -1,5 +1,6 @@
1
1
  export function objectValidation(keysToFallback) {
2
2
  return {
3
+ name: 'object',
3
4
  type: 'low',
4
5
  callback: async (value, path, options)=>{
5
6
  const isNotAnObject = typeof value !== 'object' && Array.isArray(value) === false && value !== null;