@palmares/schemas 0.0.1 → 0.1.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 (175) hide show
  1. package/.turbo/turbo-build$colon$watch.log +12 -410
  2. package/.turbo/turbo-build.log +13 -4
  3. package/CHANGELOG.md +26 -0
  4. package/__tests__/.drizzle/migrations/0000_skinny_harrier.sql +22 -0
  5. package/__tests__/.drizzle/migrations/meta/0000_snapshot.json +156 -0
  6. package/__tests__/.drizzle/migrations/meta/_journal.json +13 -0
  7. package/__tests__/.drizzle/schema.ts +35 -0
  8. package/__tests__/drizzle.config.ts +11 -0
  9. package/__tests__/eslint.config.js +10 -0
  10. package/__tests__/manage.ts +5 -0
  11. package/__tests__/node_modules/.bin/drizzle-kit +17 -0
  12. package/__tests__/node_modules/.bin/esbuild +14 -0
  13. package/__tests__/node_modules/.bin/tsc +17 -0
  14. package/__tests__/node_modules/.bin/tsserver +17 -0
  15. package/__tests__/node_modules/.bin/tsx +17 -0
  16. package/__tests__/package.json +36 -0
  17. package/__tests__/sqlite.db +0 -0
  18. package/__tests__/src/core/array.test.ts +130 -0
  19. package/__tests__/src/core/boolean.test.ts +66 -0
  20. package/__tests__/src/core/datetime.test.ts +102 -0
  21. package/__tests__/src/core/index.ts +35 -0
  22. package/__tests__/src/core/model.test.ts +260 -0
  23. package/__tests__/src/core/models.ts +50 -0
  24. package/__tests__/src/core/numbers.test.ts +177 -0
  25. package/__tests__/src/core/object.test.ts +198 -0
  26. package/__tests__/src/core/string.test.ts +222 -0
  27. package/__tests__/src/core/test.test.ts +59 -0
  28. package/__tests__/src/core/types.test.ts +97 -0
  29. package/__tests__/src/core/union.test.ts +99 -0
  30. package/__tests__/src/settings.ts +71 -0
  31. package/__tests__/tsconfig.json +11 -0
  32. package/dist/cjs/src/adapter/fields/index.js +2 -2
  33. package/dist/cjs/src/adapter/fields/object.js +9 -0
  34. package/dist/cjs/src/adapter/index.js +1 -0
  35. package/dist/cjs/src/constants.js +1 -7
  36. package/dist/cjs/src/domain.js +146 -1
  37. package/dist/cjs/src/index.js +69 -74
  38. package/dist/cjs/src/model.js +206 -206
  39. package/dist/cjs/src/schema/array.js +185 -58
  40. package/dist/cjs/src/schema/boolean.js +105 -44
  41. package/dist/cjs/src/schema/datetime.js +104 -38
  42. package/dist/cjs/src/schema/number.js +134 -114
  43. package/dist/cjs/src/schema/object.js +106 -43
  44. package/dist/cjs/src/schema/schema.js +123 -75
  45. package/dist/cjs/src/schema/string.js +152 -58
  46. package/dist/cjs/src/schema/union.js +412 -290
  47. package/dist/cjs/src/utils.js +42 -15
  48. package/dist/cjs/src/validators/array.js +6 -1
  49. package/dist/cjs/src/validators/boolean.js +2 -0
  50. package/dist/cjs/src/validators/datetime.js +4 -0
  51. package/dist/cjs/src/validators/number.js +12 -40
  52. package/dist/cjs/src/validators/object.js +1 -0
  53. package/dist/cjs/src/validators/schema.js +5 -1
  54. package/dist/cjs/src/validators/string.js +30 -2
  55. package/dist/cjs/src/validators/union.js +5 -4
  56. package/dist/cjs/src/validators/utils.js +99 -27
  57. package/dist/cjs/tsconfig.types.tsbuildinfo +1 -1
  58. package/dist/cjs/types/adapter/fields/array.d.ts +2 -2
  59. package/dist/cjs/types/adapter/fields/array.d.ts.map +1 -1
  60. package/dist/cjs/types/adapter/fields/boolean.d.ts.map +1 -1
  61. package/dist/cjs/types/adapter/fields/datetime.d.ts.map +1 -1
  62. package/dist/cjs/types/adapter/fields/index.d.ts +2 -2
  63. package/dist/cjs/types/adapter/fields/index.d.ts.map +1 -1
  64. package/dist/cjs/types/adapter/fields/number.d.ts.map +1 -1
  65. package/dist/cjs/types/adapter/fields/object.d.ts +2 -1
  66. package/dist/cjs/types/adapter/fields/object.d.ts.map +1 -1
  67. package/dist/cjs/types/adapter/fields/string.d.ts.map +1 -1
  68. package/dist/cjs/types/adapter/fields/union.d.ts.map +1 -1
  69. package/dist/cjs/types/adapter/index.d.ts +1 -0
  70. package/dist/cjs/types/adapter/index.d.ts.map +1 -1
  71. package/dist/cjs/types/adapter/types.d.ts +28 -18
  72. package/dist/cjs/types/adapter/types.d.ts.map +1 -1
  73. package/dist/cjs/types/constants.d.ts +0 -1
  74. package/dist/cjs/types/constants.d.ts.map +1 -1
  75. package/dist/cjs/types/domain.d.ts +5 -4
  76. package/dist/cjs/types/domain.d.ts.map +1 -1
  77. package/dist/cjs/types/index.d.ts +78 -55
  78. package/dist/cjs/types/index.d.ts.map +1 -1
  79. package/dist/cjs/types/model.d.ts +17 -17
  80. package/dist/cjs/types/model.d.ts.map +1 -1
  81. package/dist/cjs/types/schema/array.d.ts +168 -47
  82. package/dist/cjs/types/schema/array.d.ts.map +1 -1
  83. package/dist/cjs/types/schema/boolean.d.ts +103 -44
  84. package/dist/cjs/types/schema/boolean.d.ts.map +1 -1
  85. package/dist/cjs/types/schema/datetime.d.ts +90 -30
  86. package/dist/cjs/types/schema/datetime.d.ts.map +1 -1
  87. package/dist/cjs/types/schema/number.d.ts +133 -125
  88. package/dist/cjs/types/schema/number.d.ts.map +1 -1
  89. package/dist/cjs/types/schema/object.d.ts +104 -35
  90. package/dist/cjs/types/schema/object.d.ts.map +1 -1
  91. package/dist/cjs/types/schema/schema.d.ts +62 -44
  92. package/dist/cjs/types/schema/schema.d.ts.map +1 -1
  93. package/dist/cjs/types/schema/string.d.ts +152 -65
  94. package/dist/cjs/types/schema/string.d.ts.map +1 -1
  95. package/dist/cjs/types/schema/types.d.ts +11 -2
  96. package/dist/cjs/types/schema/types.d.ts.map +1 -1
  97. package/dist/cjs/types/schema/union.d.ts +133 -40
  98. package/dist/cjs/types/schema/union.d.ts.map +1 -1
  99. package/dist/cjs/types/types.d.ts +35 -0
  100. package/dist/cjs/types/types.d.ts.map +1 -1
  101. package/dist/cjs/types/utils.d.ts +41 -27
  102. package/dist/cjs/types/utils.d.ts.map +1 -1
  103. package/dist/cjs/types/validators/array.d.ts.map +1 -1
  104. package/dist/cjs/types/validators/boolean.d.ts.map +1 -1
  105. package/dist/cjs/types/validators/datetime.d.ts.map +1 -1
  106. package/dist/cjs/types/validators/number.d.ts +5 -6
  107. package/dist/cjs/types/validators/number.d.ts.map +1 -1
  108. package/dist/cjs/types/validators/object.d.ts.map +1 -1
  109. package/dist/cjs/types/validators/schema.d.ts +2 -2
  110. package/dist/cjs/types/validators/schema.d.ts.map +1 -1
  111. package/dist/cjs/types/validators/string.d.ts +9 -9
  112. package/dist/cjs/types/validators/string.d.ts.map +1 -1
  113. package/dist/cjs/types/validators/utils.d.ts +44 -27
  114. package/dist/cjs/types/validators/utils.d.ts.map +1 -1
  115. package/dist/esm/src/adapter/fields/index.js +2 -2
  116. package/dist/esm/src/adapter/fields/object.js +6 -0
  117. package/dist/esm/src/adapter/index.js +1 -0
  118. package/dist/esm/src/constants.js +1 -2
  119. package/dist/esm/src/domain.js +11 -1
  120. package/dist/esm/src/index.js +38 -73
  121. package/dist/esm/src/model.js +83 -78
  122. package/dist/esm/src/schema/array.js +136 -54
  123. package/dist/esm/src/schema/boolean.js +98 -44
  124. package/dist/esm/src/schema/datetime.js +91 -38
  125. package/dist/esm/src/schema/number.js +127 -110
  126. package/dist/esm/src/schema/object.js +98 -43
  127. package/dist/esm/src/schema/schema.js +102 -67
  128. package/dist/esm/src/schema/string.js +147 -59
  129. package/dist/esm/src/schema/union.js +119 -40
  130. package/dist/esm/src/types.js +14 -1
  131. package/dist/esm/src/utils.js +56 -27
  132. package/dist/esm/src/validators/array.js +6 -1
  133. package/dist/esm/src/validators/boolean.js +2 -0
  134. package/dist/esm/src/validators/datetime.js +4 -0
  135. package/dist/esm/src/validators/number.js +9 -23
  136. package/dist/esm/src/validators/object.js +1 -0
  137. package/dist/esm/src/validators/schema.js +5 -1
  138. package/dist/esm/src/validators/string.js +30 -2
  139. package/dist/esm/src/validators/union.js +5 -4
  140. package/dist/esm/src/validators/utils.js +62 -36
  141. package/package.json +3 -3
  142. package/src/adapter/fields/array.ts +2 -2
  143. package/src/adapter/fields/boolean.ts +3 -8
  144. package/src/adapter/fields/datetime.ts +3 -9
  145. package/src/adapter/fields/index.ts +11 -11
  146. package/src/adapter/fields/number.ts +3 -9
  147. package/src/adapter/fields/object.ts +13 -10
  148. package/src/adapter/fields/string.ts +3 -9
  149. package/src/adapter/fields/union.ts +3 -9
  150. package/src/adapter/index.ts +1 -0
  151. package/src/adapter/types.ts +60 -45
  152. package/src/constants.ts +1 -3
  153. package/src/domain.ts +15 -1
  154. package/src/index.ts +189 -211
  155. package/src/model.ts +119 -115
  156. package/src/schema/array.ts +274 -90
  157. package/src/schema/boolean.ts +145 -60
  158. package/src/schema/datetime.ts +133 -49
  159. package/src/schema/number.ts +210 -173
  160. package/src/schema/object.ts +167 -74
  161. package/src/schema/schema.ts +205 -126
  162. package/src/schema/string.ts +221 -94
  163. package/src/schema/types.ts +44 -16
  164. package/src/schema/union.ts +193 -68
  165. package/src/types.ts +53 -0
  166. package/src/utils.ts +115 -57
  167. package/src/validators/array.ts +46 -27
  168. package/src/validators/boolean.ts +13 -7
  169. package/src/validators/datetime.ts +24 -16
  170. package/src/validators/number.ts +53 -63
  171. package/src/validators/object.ts +6 -5
  172. package/src/validators/schema.ts +33 -25
  173. package/src/validators/string.ts +122 -59
  174. package/src/validators/union.ts +8 -8
  175. package/src/validators/utils.ts +67 -42
@@ -4,7 +4,7 @@ import { formatErrorFromParseMethod } from '../utils';
4
4
  import type {
5
5
  DefinitionsOfSchemaType,
6
6
  OnlyFieldAdaptersFromSchemaAdapter,
7
- ValidationFallbackCallbackReturnType,
7
+ ValidationFallbackCallbackReturnType
8
8
  } from './types';
9
9
  import type SchemaAdapter from '../adapter';
10
10
  import type FieldAdapter from '../adapter/fields';
@@ -25,13 +25,17 @@ export default class Schema<
25
25
  output: any;
26
26
  representation: any;
27
27
  },
28
- TDefinitions extends DefinitionsOfSchemaType = DefinitionsOfSchemaType,
28
+ TDefinitions extends DefinitionsOfSchemaType = DefinitionsOfSchemaType
29
29
  > {
30
- // Those functions will assume control of the validation process on adapters, instead of the schema. Why this is used? The idea is that the Schema has NO idea
31
- // that one of it's children might be an UnionSchema for example. The adapter might not support unions, so then we give control to the union. The parent schema
32
- // Will already have an array of translated adapter schemas. This means for a union with Number and String it'll generate two schemas, one for number and one for the value as String.
33
- // Of course this gets multiplied. So if we have a union with Number and String. We should take those two schemas from the array and validate them individually. This logic is
34
- // handled by the union schema. If we have an intersection type for example, instead of validating One schema OR the other, we validate one schema AND the other. This will be handled
30
+ // Those functions will assume control of the validation process on adapters, instead of the schema.
31
+ // Why this is used? The idea is that the Schema has NO idea
32
+ // that one of it's children might be an UnionSchema for example. The adapter might not support unions,
33
+ // so then we give control to the union. The parent schema will already have an array of translated
34
+ // adapter schemas. This means for a union with Number and String it'll generate two schemas, one for number
35
+ // and one for the value as String. Of course this gets multiplied. So if we have a union with Number and String.
36
+ // We should take those two schemas from the array and validate them individually. This logic is
37
+ // handled by the union schema. If we have an intersection type for example, instead of validating
38
+ // One schema OR the other, we validate one schema AND the other. This will be handled
35
39
  // by the schema that contains that intersection logic.
36
40
  protected __beforeValidationCallbacks: Map<
37
41
  string,
@@ -48,16 +52,16 @@ export default class Schema<
48
52
  ) => ReturnType<Schema['__validateByAdapter']>
49
53
  > = new Map();
50
54
 
51
- protected __cachedGetParent?: (() => Schema<any, any>);
52
- protected set __getParent(value: (() => Schema<any, any>)) {
55
+ protected __cachedGetParent?: () => Schema<any, any>;
56
+ protected set __getParent(value: () => Schema<any, any>) {
53
57
  this.__cachedGetParent = value;
54
58
  }
55
59
  protected get __getParent(): (() => Schema<any, any>) | undefined {
56
- return this.__cachedGetParent
60
+ return this.__cachedGetParent;
57
61
  }
58
62
 
59
- protected __alreadyAppliedModel = false;
60
- protected __runBeforeParseAndData?: (self: any) => Promise<void>
63
+ protected __alreadyAppliedModel?: Promise<any>;
64
+ protected __runBeforeParseAndData?: (self: any) => Promise<void>;
61
65
  protected __rootFallbacksValidator!: Validator;
62
66
  protected __saveCallback?: (value: any) => Promise<any | void> | any | void;
63
67
  protected __modelOmitCallback?: () => void;
@@ -79,29 +83,35 @@ export default class Schema<
79
83
  high: new Map(),
80
84
  medium: new Map(),
81
85
  low: new Map(),
82
- _fallbacks: new Set(),
86
+ _fallbacks: new Set()
83
87
  };
84
- protected __refinements: ((value: any) => Promise<void | undefined | { code: string; message: string }> | void | undefined | { code: string; message: string })[] = [];
88
+ protected __refinements: ((
89
+ value: any
90
+ ) =>
91
+ | Promise<void | undefined | { code: string; message: string }>
92
+ | void
93
+ | undefined
94
+ | { code: string; message: string })[] = [];
85
95
  protected __nullable: {
86
96
  message: string;
87
97
  allow: boolean;
88
98
  } = {
89
99
  message: 'Cannot be null',
90
- allow: false,
100
+ allow: false
91
101
  };
92
102
  protected __optional: {
93
103
  message: string;
94
104
  allow: boolean;
95
105
  } = {
96
106
  message: 'Required',
97
- allow: false,
107
+ allow: false
98
108
  };
99
- protected __extends: {
100
- callback: (
101
- schema: any
102
- ) => any,
103
- toStringCallback?: (schemaAsString: string) => string
104
- } | undefined = undefined;
109
+ protected __extends:
110
+ | {
111
+ callback: (schema: any) => any;
112
+ toStringCallback?: (schemaAsString: string) => string;
113
+ }
114
+ | undefined = undefined;
105
115
 
106
116
  protected __transformedSchemas: Record<
107
117
  string,
@@ -120,11 +130,24 @@ export default class Schema<
120
130
  check: (value: TType['input']) => boolean;
121
131
  } = {
122
132
  message: 'Invalid type',
123
- check: () => true,
133
+ check: () => true
124
134
  };
125
135
 
136
+ protected __getDefaultTransformedSchemas() {
137
+ const adapterInstance = getDefaultAdapter();
138
+
139
+ // eslint-disable-next-line ts/no-unnecessary-condition
140
+ if (this.__transformedSchemas[adapterInstance.constructor.name] === undefined)
141
+ this.__transformedSchemas[adapterInstance.constructor.name] = {
142
+ transformed: false,
143
+ adapter: adapterInstance,
144
+ schemas: []
145
+ };
146
+ }
147
+
126
148
  /**
127
- * This will validate the data with the fallbacks, so internally, without relaying on the schema adapter. This is nice because we can support things that the schema adapter is not able to support by default.
149
+ * This will validate the data with the fallbacks, so internally, without relaying on the schema adapter.
150
+ * This is nice because we can support things that the schema adapter is not able to support by default.
128
151
  *
129
152
  * @param errorsAsHashedSet - The errors as a hashed set. This is used to prevent duplicate errors.
130
153
  * @param path - The path of the error.
@@ -140,15 +163,17 @@ export default class Schema<
140
163
  ) {
141
164
  // eslint-disable-next-line ts/no-unnecessary-condition
142
165
  if (this.__rootFallbacksValidator)
143
- return this.__rootFallbacksValidator.validate(options.errorsAsHashedSet || new Set(), path, parseResult, options);
166
+ return this.__rootFallbacksValidator.validate(options.errorsAsHashedSet as Set<any>, path, parseResult, options);
144
167
 
145
168
  return parseResult;
146
169
  }
147
170
 
148
171
  /**
149
- * This will validate by the adapter. In other words, we send the data to the schema adapter and then we validate that data.
150
- * So understand that, first we send the data to the adapter, the adapter validates it, then, after we validate from the adapter
151
- * we validate with the fallbacks so we can do all of the extra validations not handled by the adapter.
172
+ * This will validate by the adapter. In other words, we send the data to the schema adapter and then we validate
173
+ * that data.
174
+ * So understand that, first we send the data to the adapter, the adapter validates it, then, after we validate
175
+ * from the adapter we validate with the fallbacks so we can do all of the extra validations not handled by
176
+ * the adapter.
152
177
  *
153
178
  * @param value - The value to be validated.
154
179
  * @param errorsAsHashedSet - The errors as a hashed set. This is used to prevent duplicate errors on the validator.
@@ -167,7 +192,7 @@ export default class Schema<
167
192
  ) {
168
193
  const parseResult: Awaited<ReturnType<Schema['__parse']>> = {
169
194
  errors: [],
170
- parsed: value,
195
+ parsed: value
171
196
  };
172
197
  // On the next iteration we will reset the errors and the parsed value
173
198
  parseResult.errors = [];
@@ -176,7 +201,13 @@ export default class Schema<
176
201
  // eslint-disable-next-line ts/no-unnecessary-condition
177
202
  if (fieldAdapter === undefined || typeof fieldAdapter.parse !== 'function') return parseResult;
178
203
 
179
- const adapterParseResult = await fieldAdapter.parse(adapter, adapter.field, schema.transformed, value, options.args);
204
+ const adapterParseResult = await fieldAdapter.parse(
205
+ adapter,
206
+ adapter.field,
207
+ schema.transformed,
208
+ value,
209
+ options.args
210
+ );
180
211
 
181
212
  parseResult.parsed = adapterParseResult.parsed;
182
213
 
@@ -184,7 +215,15 @@ export default class Schema<
184
215
  if (Array.isArray(adapterParseResult.errors))
185
216
  parseResult.errors = await Promise.all(
186
217
  adapterParseResult.errors.map(async (error) =>
187
- formatErrorFromParseMethod(adapter, fieldAdapter, error, path, options.errorsAsHashedSet || new Set())
218
+ formatErrorFromParseMethod(
219
+ adapter,
220
+ fieldAdapter,
221
+ error,
222
+ value,
223
+ schema.transformed,
224
+ path,
225
+ options.errorsAsHashedSet || new Set()
226
+ )
188
227
  )
189
228
  );
190
229
  else
@@ -193,24 +232,28 @@ export default class Schema<
193
232
  adapter,
194
233
  fieldAdapter,
195
234
  parseResult.errors,
235
+ value,
236
+ schema.transformed,
196
237
  path,
197
238
  options.errorsAsHashedSet || new Set()
198
- ),
239
+ )
199
240
  ];
200
241
  }
242
+ parseResult.errors = parseResult.errors.filter((error) => typeof error !== 'undefined');
201
243
  return parseResult;
202
244
  }
203
245
 
204
246
  // eslint-disable-next-line ts/require-await
205
247
  protected async __transformToAdapter(_options: {
206
248
  // force to transform
207
- args: Omit<ValidationDataBasedOnType<any>, 'withFallback'>
249
+ args: Omit<ValidationDataBasedOnType<any>, 'withFallback'>;
208
250
  force?: boolean;
209
251
  toInternalToBubbleUp?: (() => Promise<void>)[];
210
252
  schemaAdapter?: SchemaAdapter;
211
253
  errorsAsHashedSet?: Set<string>;
212
254
  shouldAddStringVersion?: boolean;
213
255
  appendFallbacksBeforeAdapterValidation?: (
256
+ schema: Schema<any, any>,
214
257
  uniqueNameOfFallback: string,
215
258
  fallbackValidationBeforeAdapter: (
216
259
  adapterToUse: SchemaAdapter,
@@ -236,6 +279,7 @@ export default class Schema<
236
279
  /** */
237
280
  protected async __parsersToTransformValue(value: any, parsersToUse?: Set<string>) {
238
281
  let shouldStop = false;
282
+
239
283
  for (const [parserName, parser] of this.__parsers.high.entries()) {
240
284
  if (parsersToUse instanceof Set === false || parsersToUse.has(parserName)) {
241
285
  const result = await Promise.resolve(parser(value));
@@ -270,11 +314,16 @@ export default class Schema<
270
314
  path: ValidationFallbackCallbackReturnType['errors'][number]['path'] = [],
271
315
  options: Parameters<Schema['__transformToAdapter']>[0]
272
316
  ): Promise<{ errors: any[]; parsed: TType['internal'] }> {
317
+ this.__getDefaultTransformedSchemas();
273
318
  if (typeof this.__runBeforeParseAndData === 'function') await this.__runBeforeParseAndData(this);
274
- // This is used to run the toInternal command. If we didn't do this, we would need to parse through all of the schemas to run the toInternal command,
275
- // from the leafs (ObjectSchemas) to the root schema. This is not a good idea, so what we do is that during validation the leafs attach a function to
276
- // the options.toInternalToBubbleUp like `options.toInternalToBubbleUp.push(async () => (value[key] = await (schema as any).__toInternal(parsed)));``
277
- // This way, when the root schema finishes the validation, it will run all of the functions in the toInternalToBubbleUp array, modifying the parsed value.
319
+
320
+ // This is used to run the toInternal command. If we didn't do this, we would need to parse through all of
321
+ // the schemas to run the toInternal command, from the leafs (ObjectSchemas) to the root schema. This is not
322
+ // a good idea, so what we do is that during validation the leafs attach a function to the
323
+ // options.toInternalToBubbleUp like
324
+ // `options.toInternalToBubbleUp.push(async () => (value[key] = await (schema as any).__toInternal(parsed)));``
325
+ // This way, when the root schema finishes the validation, it will run all of the functions in the
326
+ // toInternalToBubbleUp array, modifying the parsed value.
278
327
  const shouldRunToInternalToBubbleUp = options.toInternalToBubbleUp === undefined;
279
328
  if (shouldRunToInternalToBubbleUp) options.toInternalToBubbleUp = [];
280
329
  if (options.errorsAsHashedSet instanceof Set === false) options.errorsAsHashedSet = new Set();
@@ -292,17 +341,21 @@ export default class Schema<
292
341
  errors: ValidationFallbackCallbackReturnType['errors'];
293
342
  parsed: TType['input'];
294
343
  } = { errors: [], parsed: value };
344
+ value = await this.__parsersToTransformValue(value, this.__parsers._fallbacks);
295
345
 
296
346
  if (options.appendFallbacksBeforeAdapterValidation === undefined)
297
- options.appendFallbacksBeforeAdapterValidation = (name, callback) => {
298
- this.__beforeValidationCallbacks.set(name, callback);
347
+ options.appendFallbacksBeforeAdapterValidation = (schema, name, callback) => {
348
+ // We just need this if the union adapter is net defined but the parent is not of the same type.
349
+ // For example, it's a union child of o object schema
350
+ if (this !== schema) this.__beforeValidationCallbacks.set(name, callback);
299
351
  };
300
352
 
301
- if (this.__transformedSchemas[options.schemaAdapter?.constructor.name || getDefaultAdapter().constructor.name].transformed === false)
353
+ if (
354
+ this.__transformedSchemas[options.schemaAdapter?.constructor.name || getDefaultAdapter().constructor.name]
355
+ .transformed === false
356
+ )
302
357
  await this.__transformToAdapter(options);
303
358
 
304
- value = await this.__parsersToTransformValue(value, this.__parsers._fallbacks);
305
-
306
359
  const adapterToUse = options.schemaAdapter
307
360
  ? options.schemaAdapter
308
361
  : Object.values(this.__transformedSchemas)[0].adapter;
@@ -310,8 +363,8 @@ export default class Schema<
310
363
  const parsedResultsAfterFallbacks = await this.__validateByFallbacks(
311
364
  path,
312
365
  {
313
- errors: [],
314
- parsed: value,
366
+ errors: parseResult.errors,
367
+ parsed: value
315
368
  },
316
369
  options
317
370
  );
@@ -319,7 +372,8 @@ export default class Schema<
319
372
  parseResult.parsed = parsedResultsAfterFallbacks.parsed;
320
373
  // eslint-disable-next-line ts/no-unnecessary-condition
321
374
  parseResult.errors = (parseResult.errors || []).concat(parsedResultsAfterFallbacks.errors || []);
322
- // With this, the children takes control of validating by the adapter. For example on a union schema we want to validate all of the schemas and choose the one that has no errors.
375
+ // With this, the children takes control of validating by the adapter. For example on a union schema we
376
+ // want to validate all of the schemas and choose the one that has no errors.
323
377
  if (this.__beforeValidationCallbacks.size > 0) {
324
378
  for (const callback of this.__beforeValidationCallbacks.values()) {
325
379
  const parsedValuesAfterValidationCallbacks = await callback(
@@ -332,7 +386,13 @@ export default class Schema<
332
386
  options
333
387
  );
334
388
  parseResult.parsed = parsedValuesAfterValidationCallbacks.parsed;
335
- parseResult.errors = parsedValuesAfterValidationCallbacks.errors;
389
+
390
+ parseResult.errors =
391
+ Array.isArray(parseResult.errors) && Array.isArray(parsedValuesAfterValidationCallbacks.errors)
392
+ ? [...parseResult.errors, ...parsedValuesAfterValidationCallbacks.errors]
393
+ : Array.isArray(parseResult.errors)
394
+ ? parseResult.errors
395
+ : parsedValuesAfterValidationCallbacks.errors;
336
396
  }
337
397
  } else {
338
398
  const parsedValuesAfterValidatingByAdapter = await this.__validateByAdapter(
@@ -343,30 +403,33 @@ export default class Schema<
343
403
  path,
344
404
  options
345
405
  );
406
+
346
407
  parseResult.parsed = parsedValuesAfterValidatingByAdapter.parsed;
347
408
  // eslint-disable-next-line ts/no-unnecessary-condition
348
409
  parseResult.errors = (parseResult.errors || []).concat(parsedValuesAfterValidatingByAdapter.errors);
349
410
  }
350
411
 
351
-
352
- const doesNotHaveErrors = !Array.isArray(parseResult.errors) || parseResult.errors.length === 0;
353
412
  const hasToInternalCallback = typeof this.__toInternal === 'function';
354
413
  const shouldCallToInternalDuringParse =
355
- doesNotHaveErrors && hasToInternalCallback && Array.isArray(options.toInternalToBubbleUp) === false;
414
+ hasToInternalCallback &&
415
+ (options.toInternalToBubbleUp?.length === 0 || Array.isArray(options.toInternalToBubbleUp) === false);
356
416
  // eslint-disable-next-line ts/no-unnecessary-condition
357
417
  const hasNoErrors = parseResult.errors === undefined || (parseResult.errors || []).length === 0;
358
418
 
359
- await Promise.all(this.__refinements.map(async (refinement) => {
360
- const errorOrNothing = await Promise.resolve(refinement(parseResult.parsed));
361
-
362
- if (typeof errorOrNothing === 'undefined') return;
363
- parseResult.errors.push({
364
- isValid: false,
365
- code: errorOrNothing.code as any,
366
- message: errorOrNothing.message,
367
- path,
368
- });
369
- }));
419
+ await Promise.all(
420
+ this.__refinements.map(async (refinement) => {
421
+ const errorOrNothing = await Promise.resolve(refinement(parseResult.parsed));
422
+
423
+ if (typeof errorOrNothing === 'undefined') return;
424
+ parseResult.errors.push({
425
+ isValid: false,
426
+ code: errorOrNothing.code as any,
427
+ message: errorOrNothing.message,
428
+ received: parseResult.parsed,
429
+ path
430
+ });
431
+ })
432
+ );
370
433
 
371
434
  if (shouldCallToInternalDuringParse && hasNoErrors) parseResult.parsed = await (this.__toInternal as any)(value);
372
435
  if (shouldRunToInternalToBubbleUp && hasNoErrors)
@@ -376,7 +439,8 @@ export default class Schema<
376
439
  }
377
440
 
378
441
  /**
379
- * 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.
442
+ * This let's you refine the schema with custom validations. This is useful when you want to validate something
443
+ * that is not supported by default by the schema adapter.
380
444
  *
381
445
  * @example
382
446
  * ```typescript
@@ -388,7 +452,8 @@ export default class Schema<
388
452
  *
389
453
  * const { errors, parsed } = await numberSchema.parse(-1);
390
454
  *
391
- * console.log(errors); // [{ isValid: false, code: 'invalid_number', message: 'The number should be greater than 0', path: [] }]
455
+ * console.log(errors);
456
+ * // [{ isValid: false, code: 'invalid_number', message: 'The number should be greater than 0', path: [] }]
392
457
  * ```
393
458
  *
394
459
  * @param refinementCallback - The callback that will be called to validate the value.
@@ -396,7 +461,13 @@ export default class Schema<
396
461
  * @param options.isAsync - Whether the callback is async or not. Defaults to true.
397
462
  */
398
463
  refine(
399
- refinementCallback: (value: TType['input']) => Promise<void | undefined | { code: string; message: string }> | void | undefined | { code: string; message: string }
464
+ refinementCallback: (
465
+ value: TType['input']
466
+ ) =>
467
+ | Promise<void | undefined | { code: string; message: string }>
468
+ | void
469
+ | undefined
470
+ | { code: string; message: string }
400
471
  ) {
401
472
  this.__refinements.push(refinementCallback);
402
473
 
@@ -407,7 +478,8 @@ export default class Schema<
407
478
  internal: TType['internal'];
408
479
  output: TType['output'];
409
480
  representation: TType['representation'];
410
- }, TDefinitions
481
+ },
482
+ TDefinitions
411
483
  >;
412
484
  }
413
485
 
@@ -438,7 +510,7 @@ export default class Schema<
438
510
  optional(options?: { message?: string; allow?: false }) {
439
511
  this.__optional = {
440
512
  message: typeof options?.message === 'string' ? options.message : 'Required',
441
- allow: typeof options?.allow === 'boolean' ? options.allow : true,
513
+ allow: typeof options?.allow === 'boolean' ? options.allow : true
442
514
  };
443
515
 
444
516
  return this as unknown as Schema<
@@ -454,8 +526,8 @@ export default class Schema<
454
526
  }
455
527
 
456
528
  /**
457
- * 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
458
- * the { message: 'Your custom message', allow: false } on the options.
529
+ * Allows the value to be null and ONLY null. You can also use this function to set a custom message when
530
+ * the value is NULL by setting the { message: 'Your custom message', allow: false } on the options.
459
531
  *
460
532
  * @example
461
533
  * ```typescript
@@ -481,7 +553,7 @@ export default class Schema<
481
553
  nullable(options?: { message: string; allow: false }) {
482
554
  this.__nullable = {
483
555
  message: typeof options?.message === 'string' ? options.message : 'Cannot be null',
484
- allow: typeof options?.allow === 'boolean' ? options.allow : true,
556
+ allow: typeof options?.allow === 'boolean' ? options.allow : true
485
557
  };
486
558
 
487
559
  return this as unknown as Schema<
@@ -499,8 +571,8 @@ export default class Schema<
499
571
  /**
500
572
  * Appends a custom schema to the schema, this way it will bypass the creation of the schema in runtime.
501
573
  *
502
- * By default when validating, on the first validation we create the schema. Just during the first validation. With this function, you bypass that,
503
- * so you can speed up the validation process.
574
+ * By default when validating, on the first validation we create the schema. Just during the first validation.
575
+ * With this function, you bypass that, so you can speed up the validation process.
504
576
  *
505
577
  * @example
506
578
  * ```typescript
@@ -524,7 +596,7 @@ export default class Schema<
524
596
  this.__transformedSchemas[adapter.constructor.name] = {
525
597
  transformed: true,
526
598
  adapter: adapter,
527
- schemas: [schema],
599
+ schemas: [schema]
528
600
  };
529
601
 
530
602
  return this as unknown as Schema<
@@ -540,14 +612,15 @@ export default class Schema<
540
612
  }
541
613
 
542
614
  /**
543
- * This method will remove the value from the representation of the schema. If the value is undefined it will keep that way
544
- * otherwise it will set the value to undefined after it's validated.
615
+ * This method will remove the value from the representation of the schema. If the value is undefined it will keep
616
+ * that way otherwise it will set the value to undefined after it's validated.
545
617
  * This is used in conjunction with the {@link data} function, the {@link parse} function or {@link validate}
546
618
  * function. This will remove the value from the representation of the schema.
547
619
  *
548
- * By default, the value will be removed just from the representation, in other words, when you call the {@link data} function.
549
- * But if you want to remove the value from the internal representation, you can pass the argument `toInternal` as true.
550
- * Then if you still want to remove the value from the representation, you will need to pass the argument `toRepresentation` as true as well.
620
+ * By default, the value will be removed just from the representation, in other words, when you call the {@link data}
621
+ * function. But if you want to remove the value from the internal representation, you can pass the argument
622
+ * `toInternal` as true. Then if you still want to remove the value from the representation, you will need to pass
623
+ * the argument `toRepresentation` as true as well.
551
624
  *
552
625
  * @example
553
626
  * ```typescript
@@ -569,18 +642,21 @@ export default class Schema<
569
642
  * ```
570
643
  *
571
644
  *
572
- * @param args - By default, the value will be removed just from the representation, in other words, when you call the {@link data} function.
573
- * But if you want to remove the value from the internal representation, you can pass the argument `toInternal` as true.
574
- * Then if you still want to remove the value from the representation, you will need to pass the argument `toRepresentation` as true as well.
645
+ * @param args - By default, the value will be removed just from the representation, in other words, when you call
646
+ * the {@link data} function.
647
+ * But if you want to remove the value from the internal representation, you can pass the argument `toInternal`
648
+ * as true. Then if you still want to remove the value from the representation, you will need to pass the
649
+ * argument `toRepresentation` as true as well.
575
650
  *
576
651
  * @returns The schema.
577
652
  */
578
653
  omit<
579
654
  TToInternal extends boolean,
580
655
  TToRepresentation extends boolean = boolean extends TToInternal ? true : false
581
- >(args?: { toInternal?: TToInternal, toRepresentation?: TToRepresentation }) {
656
+ >(args?: { toInternal?: TToInternal; toRepresentation?: TToRepresentation }) {
582
657
  // To representation is true by default, unless to internal is true.
583
- const toRepresentation = typeof args?.toRepresentation === 'boolean' ? args.toRepresentation : typeof args?.toInternal !== 'boolean';
658
+ const toRepresentation =
659
+ typeof args?.toRepresentation === 'boolean' ? args.toRepresentation : typeof args?.toInternal !== 'boolean';
584
660
  const toInternal = typeof args?.toInternal === 'boolean' ? args.toInternal : false;
585
661
 
586
662
  if (toInternal) {
@@ -590,7 +666,7 @@ export default class Schema<
590
666
  await toInternal(value);
591
667
  return undefined;
592
668
  };
593
- // eslint-disable-next-line ts/require-await
669
+ // eslint-disable-next-line ts/require-await
594
670
  } else this.__toInternal = async () => undefined;
595
671
  } else if (toRepresentation) {
596
672
  if (this.__toRepresentation) {
@@ -599,7 +675,7 @@ export default class Schema<
599
675
  await toRepresentation(value);
600
676
  return undefined;
601
677
  };
602
- // eslint-disable-next-line ts/require-await
678
+ // eslint-disable-next-line ts/require-await
603
679
  } else this.__toRepresentation = async () => undefined;
604
680
  }
605
681
 
@@ -616,9 +692,9 @@ export default class Schema<
616
692
  }
617
693
 
618
694
  /**
619
- * This function is used in conjunction with the {@link validate} function. It's used to save a value to an external source
620
- * like a database. You should always return the schema after you save the value, that way we will always have the correct type
621
- * of the schema after the save operation.
695
+ * This function is used in conjunction with the {@link validate} function. It's used to save a value to an external
696
+ * source like a database. You should always return the schema after you save the value, that way we will always have
697
+ * the correct type of the schema after the save operation.
622
698
  *
623
699
  * You can use the {@link toRepresentation} function to transform and clean the value it returns after the save.
624
700
  *
@@ -678,10 +754,11 @@ export default class Schema<
678
754
  * This function is used to validate the schema and save the value to the database. It is used in
679
755
  * conjunction with the {@link onSave} function.
680
756
  *
681
- * Different from other validation libraries, palmares schemas is aware that you want to save. On your routes/functions
682
- * we recommend to ALWAYS use this function instead of {@link parse} directly. This is because this function by default
683
- * will return an object with the property `save` or the `errors`. If the errors are present, you can return the errors
684
- * to the user. If the save property is present, you can use to save the value to an external source. e.g. a database.
757
+ * Different from other validation libraries, palmares schemas is aware that you want to save. On your
758
+ * routes/functions we recommend to ALWAYS use this function instead of {@link parse} directly. This is because
759
+ * this function by default will return an object with the property `save` or the `errors`. If the errors are present,
760
+ * you can return the errors to the user. If the save property is present, you can use to save the value to an
761
+ * external source. e.g. a database.
685
762
  *
686
763
  * @example
687
764
  * ```typescript
@@ -765,9 +842,7 @@ export default class Schema<
765
842
  *
766
843
  * @returns The parsed value.
767
844
  */
768
- async parse(
769
- value: TType['input']
770
- ): Promise<{ errors?: any[]; parsed: TType['internal'] }> {
845
+ async parse(value: TType['input']): Promise<{ errors?: any[]; parsed: TType['internal'] }> {
771
846
  return this.__parse(value, [], {} as any);
772
847
  }
773
848
 
@@ -802,8 +877,9 @@ export default class Schema<
802
877
  * ```
803
878
  */
804
879
  async data(value: TType['output']): Promise<TType['representation']> {
880
+ this.__getDefaultTransformedSchemas();
805
881
  if (typeof this.__runBeforeParseAndData === 'function') await this.__runBeforeParseAndData(this);
806
- value = await this.__parsersToTransformValue(value)
882
+ value = await this.__parsersToTransformValue(value);
807
883
 
808
884
  if (this.__toRepresentation) value = await Promise.resolve(this.__toRepresentation(value));
809
885
  if (this.__defaultFunction && value === undefined) value = await Promise.resolve(this.__defaultFunction());
@@ -827,7 +903,8 @@ export default class Schema<
827
903
  }
828
904
 
829
905
  /**
830
- * 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.
906
+ * This function is used to add a default value to the schema. If the value is either undefined or null,
907
+ * the default value will be used.
831
908
  *
832
909
  * @example
833
910
  * ```typescript
@@ -861,8 +938,9 @@ export default class Schema<
861
938
  }
862
939
 
863
940
  /**
864
- * 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
865
- * the custom schema your own way. Our API does not support passthrough? No problem, you can use this function to customize the zod schema.
941
+ * This function let's you customize the schema your own way. After we translate the schema on the adapter we call
942
+ * this function to let you customize the custom schema your own way. Our API does not support passthrough?
943
+ * No problem, you can use this function to customize the zod schema.
866
944
  *
867
945
  * @example
868
946
  * ```typescript
@@ -874,12 +952,13 @@ export default class Schema<
874
952
  *
875
953
  * const { errors, parsed } = await numberSchema.parse(-1);
876
954
  *
877
- * console.log(errors); // [{ isValid: false, code: 'nonnegative', message: 'The number should be nonnegative', path: [] }]
955
+ * console.log(errors);
956
+ * // [{ isValid: false, code: 'nonnegative', message: 'The number should be nonnegative', path: [] }]
878
957
  * ```
879
958
  *
880
959
  * @param callback - The callback that will be called to customize the schema.
881
- * @param toStringCallback - The callback that will be called to transform the schema to a string when you want to compile the underlying schema
882
- * to a string so you can save it for future runs.
960
+ * @param toStringCallback - The callback that will be called to transform the schema to a string when you want
961
+ * to compile the underlying schema to a string so you can save it for future runs.
883
962
  *
884
963
  * @returns The schema.
885
964
  */
@@ -891,14 +970,15 @@ export default class Schema<
891
970
  ) {
892
971
  this.__extends = {
893
972
  callback,
894
- toStringCallback,
895
- }
896
- return this
973
+ toStringCallback
974
+ };
975
+ return this;
897
976
  }
898
977
 
899
978
  /**
900
- * 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
901
- * 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.
979
+ * This function is used to transform the value to the representation of the schema. When using the {@link data}
980
+ * function. With this function you have full control to add data cleaning for example, transforming the data
981
+ * and whatever. Another use case is when you want to return deeply nested recursive data.
902
982
  * The schema maps to itself.
903
983
  *
904
984
  * @example
@@ -937,25 +1017,31 @@ export default class Schema<
937
1017
  * ```
938
1018
  * @param toRepresentationCallback - The callback that will be called to transform the value to the representation.
939
1019
  * @param options - Options for the toRepresentation function.
940
- * @param options.after - Whether the toRepresentationCallback should be called after the existing toRepresentationCallback. Defaults to true.
941
- * @param options.before - Whether the toRepresentationCallback should be called before the existing toRepresentationCallback. Defaults to true.
1020
+ * @param options.after - Whether the toRepresentationCallback should be called after the existing
1021
+ * toRepresentationCallback. Defaults to true.
1022
+ * @param options.before - Whether the toRepresentationCallback should be called before the existing
1023
+ * toRepresentationCallback. Defaults to true.
942
1024
  *
943
1025
  * @returns The schema with a new return type
944
1026
  */
945
1027
  toRepresentation<TRepresentation>(
946
- toRepresentationCallback: (value: TType['representation']) => Promise<TRepresentation>,
1028
+ toRepresentationCallback: (value: TType['representation']) => Promise<TRepresentation> | TRepresentation,
947
1029
  options?: {
948
1030
  after?: boolean;
949
1031
  before?: boolean;
950
1032
  }
951
1033
  ) {
952
1034
  if (this.__toRepresentation) {
953
- const before = typeof options?.before === 'boolean' ? options.before :
954
- (typeof options?.after === 'boolean' ? !options.after : true);
1035
+ const before =
1036
+ typeof options?.before === 'boolean'
1037
+ ? options.before
1038
+ : typeof options?.after === 'boolean'
1039
+ ? !options.after
1040
+ : true;
955
1041
  const existingToRepresentation = this.__toRepresentation;
956
- console.log('existing to representation', existingToRepresentation, before, options?.after)
1042
+
957
1043
  this.__toRepresentation = async (value) => {
958
- if (before) return toRepresentationCallback(await existingToRepresentation(value))
1044
+ if (before) return toRepresentationCallback(await existingToRepresentation(value));
959
1045
  else return existingToRepresentation(await toRepresentationCallback(value));
960
1046
  };
961
1047
  } else this.__toRepresentation = toRepresentationCallback;
@@ -973,8 +1059,9 @@ export default class Schema<
973
1059
  }
974
1060
 
975
1061
  /**
976
- * 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
977
- * 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.
1062
+ * This function is used to transform the value to the internal representation of the schema. This is useful
1063
+ * when you want to transform the value to a type that the schema adapter can understand. For example, you
1064
+ * might want to transform a string to a date. This is the function you use.
978
1065
  *
979
1066
  * @example
980
1067
  * ```typescript
@@ -1026,8 +1113,9 @@ export default class Schema<
1026
1113
  }
1027
1114
 
1028
1115
  /**
1029
- * 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
1030
- * here BEFORE the validation. This pretty much transforms the value to a type that the schema adapter can understand.
1116
+ * Called before the validation of the schema. Let's say that you want to validate a date that might receive a
1117
+ * string, you can convert that string to a date here BEFORE the validation. This pretty much transforms the value
1118
+ * to a type that the schema adapter can understand.
1031
1119
  *
1032
1120
  * @example
1033
1121
  * ```
@@ -1066,7 +1154,7 @@ export default class Schema<
1066
1154
  async compile(adapter: SchemaAdapter) {
1067
1155
  const data = await this.__transformToAdapter({
1068
1156
  shouldAddStringVersion: true,
1069
- force: true,
1157
+ force: true
1070
1158
  } as any);
1071
1159
 
1072
1160
  const stringVersions = data.map((value) => value.asString);
@@ -1077,17 +1165,8 @@ export default class Schema<
1077
1165
  ..._args: any[]
1078
1166
  ): Schema<TType> {
1079
1167
  const result = new Schema<TType>();
1080
-
1081
- const adapterInstance = getDefaultAdapter();
1082
- result.__transformedSchemas[adapterInstance.constructor.name] = {
1083
- transformed: false,
1084
- adapter: adapterInstance,
1085
- schemas: [],
1086
- };
1087
-
1088
1168
  return result;
1089
1169
  }
1090
1170
  }
1091
1171
 
1092
1172
  export const schema = Schema.new;
1093
-