@palmares/schemas 0.1.21 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/package.json +10 -4
- package/.turbo/turbo-build$colon$watch.log +0 -24
- package/.turbo/turbo-build.log +0 -13
- package/.turbo/turbo-build:watch.log +0 -26
- package/__tests__/.drizzle/migrations/0000_skinny_harrier.sql +0 -22
- package/__tests__/.drizzle/migrations/meta/0000_snapshot.json +0 -156
- package/__tests__/.drizzle/migrations/meta/_journal.json +0 -13
- package/__tests__/.drizzle/schema.ts +0 -35
- package/__tests__/drizzle.config.ts +0 -11
- package/__tests__/eslint.config.js +0 -10
- package/__tests__/manage.ts +0 -5
- package/__tests__/node_modules/.bin/drizzle-kit +0 -17
- package/__tests__/node_modules/.bin/node-gyp +0 -17
- package/__tests__/node_modules/.bin/tsc +0 -17
- package/__tests__/node_modules/.bin/tsserver +0 -17
- package/__tests__/node_modules/.bin/tsx +0 -17
- package/__tests__/package.json +0 -34
- package/__tests__/sqlite.db +0 -0
- package/__tests__/src/core/array.test.ts +0 -131
- package/__tests__/src/core/boolean.test.ts +0 -66
- package/__tests__/src/core/datetime.test.ts +0 -102
- package/__tests__/src/core/index.ts +0 -35
- package/__tests__/src/core/model.test.ts +0 -260
- package/__tests__/src/core/models.ts +0 -50
- package/__tests__/src/core/numbers.test.ts +0 -177
- package/__tests__/src/core/object.test.ts +0 -218
- package/__tests__/src/core/string.test.ts +0 -222
- package/__tests__/src/core/test.test.ts +0 -59
- package/__tests__/src/core/types.test.ts +0 -97
- package/__tests__/src/core/union.test.ts +0 -99
- package/__tests__/src/settings.ts +0 -69
- package/__tests__/tsconfig.json +0 -11
- package/src/adapter/fields/array.ts +0 -31
- package/src/adapter/fields/boolean.ts +0 -43
- package/src/adapter/fields/datetime.ts +0 -43
- package/src/adapter/fields/index.ts +0 -72
- package/src/adapter/fields/number.ts +0 -43
- package/src/adapter/fields/object.ts +0 -52
- package/src/adapter/fields/string.ts +0 -43
- package/src/adapter/fields/union.ts +0 -43
- package/src/adapter/index.ts +0 -37
- package/src/adapter/types.ts +0 -276
- package/src/compile.ts +0 -14
- package/src/conf.ts +0 -30
- package/src/constants.ts +0 -7
- package/src/domain.ts +0 -15
- package/src/exceptions.ts +0 -17
- package/src/index.ts +0 -318
- package/src/middleware.ts +0 -52
- package/src/model.ts +0 -518
- package/src/parsers/convert-from-number.ts +0 -13
- package/src/parsers/convert-from-string.ts +0 -19
- package/src/parsers/index.ts +0 -2
- package/src/schema/array.ts +0 -825
- package/src/schema/boolean.ts +0 -792
- package/src/schema/datetime.ts +0 -704
- package/src/schema/index.ts +0 -5
- package/src/schema/number.ts +0 -929
- package/src/schema/object.ts +0 -799
- package/src/schema/schema.ts +0 -1179
- package/src/schema/string.ts +0 -941
- package/src/schema/types.ts +0 -154
- package/src/schema/union.ts +0 -724
- package/src/types.ts +0 -66
- package/src/utils.ts +0 -389
- package/src/validators/array.ts +0 -183
- package/src/validators/boolean.ts +0 -52
- package/src/validators/datetime.ts +0 -121
- package/src/validators/number.ts +0 -178
- package/src/validators/object.ts +0 -56
- package/src/validators/schema.ts +0 -142
- package/src/validators/string.ts +0 -278
- package/src/validators/types.ts +0 -1
- package/src/validators/union.ts +0 -52
- package/src/validators/utils.ts +0 -226
- package/tsconfig.json +0 -9
- package/tsconfig.types.json +0 -10
package/src/types.ts
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
import type { SchemaAdapter } from './adapter';
|
2
|
-
import type { Schema } from './schema/schema';
|
3
|
-
import type { ValidatorTypes } from './validators/types';
|
4
|
-
|
5
|
-
export type MaybePromise<T> = T | Promise<T>;
|
6
|
-
|
7
|
-
export type SchemasSettingsType = {
|
8
|
-
schemaAdapter: typeof SchemaAdapter;
|
9
|
-
};
|
10
|
-
|
11
|
-
export type FallbackFunctionsType<TArguments> = {
|
12
|
-
[TKey in keyof TArguments]?: (args: NonNullable<TArguments[TKey]>) => {
|
13
|
-
type: ValidatorTypes;
|
14
|
-
callback: NonNullable<Schema['__rootFallbacksValidator']['fallbacks'][number]>;
|
15
|
-
};
|
16
|
-
};
|
17
|
-
|
18
|
-
export type SupportedSchemas = 'number' | 'object' | 'union' | 'string' | 'array' | 'boolean' | 'datetime';
|
19
|
-
|
20
|
-
/**
|
21
|
-
* Retrieve the typescript type of a schema.
|
22
|
-
*
|
23
|
-
* First generic is `typeof myCustomSchema`.
|
24
|
-
*
|
25
|
-
* Second generic is:
|
26
|
-
* - 'input' - The data passed to `.parse` and `.validate` functions. Defaults to this.
|
27
|
-
* - 'output' - (use `'representation'` to get the data format you are
|
28
|
-
* passing to the user) The data passed to `.data` function to return to the
|
29
|
-
* user.
|
30
|
-
* - 'representation' - The data after `toRepresentation`, usually, use this over 'output'
|
31
|
-
* - 'internal' - The data after it's transformed for the `toSave` callback.
|
32
|
-
* - 'validate' - The data for `toValidate` callback.
|
33
|
-
*/
|
34
|
-
export type Infer<
|
35
|
-
TSchema extends Schema<any, any>,
|
36
|
-
/**
|
37
|
-
* - 'input' - The data passed to `.parse` and `.validate` functions.
|
38
|
-
* - 'output' - (use `'representation'` to get the data format you are
|
39
|
-
* passing to the user) The data passed to `.data` function to return to the
|
40
|
-
* user.
|
41
|
-
* - 'representation' - The data after `toRepresentation`, usually, use this over 'output'
|
42
|
-
* - 'internal' - The data after it's transformed for the `toSave` callback.
|
43
|
-
* - 'validate' - The data for `toValidate` callback.
|
44
|
-
*/
|
45
|
-
TType extends 'input' | 'output' | 'representation' | 'internal' | 'validate' = 'input'
|
46
|
-
> =
|
47
|
-
TSchema extends Schema<
|
48
|
-
{
|
49
|
-
input: infer TInput;
|
50
|
-
internal: infer TInternal;
|
51
|
-
output: infer TOutput;
|
52
|
-
representation: infer TRepresentation;
|
53
|
-
validate: infer TValidate;
|
54
|
-
},
|
55
|
-
any
|
56
|
-
>
|
57
|
-
? TType extends 'output'
|
58
|
-
? TOutput
|
59
|
-
: TType extends 'representation'
|
60
|
-
? TRepresentation
|
61
|
-
: TType extends 'internal'
|
62
|
-
? TInternal
|
63
|
-
: TType extends 'validate'
|
64
|
-
? TValidate
|
65
|
-
: TInput
|
66
|
-
: never;
|
package/src/utils.ts
DELETED
@@ -1,389 +0,0 @@
|
|
1
|
-
import { getDefaultAdapter } from './conf';
|
2
|
-
import { checkType, nullable, optional } from './validators/schema';
|
3
|
-
import { Validator } from './validators/utils';
|
4
|
-
|
5
|
-
import type { SchemaAdapter } from './adapter';
|
6
|
-
import type { FieldAdapter } from './adapter/fields';
|
7
|
-
import type { ValidationDataBasedOnType } from './adapter/types';
|
8
|
-
import type { Schema } from './schema/schema';
|
9
|
-
import type { ValidationFallbackCallbackReturnType, ValidationFallbackReturnType } from './schema/types';
|
10
|
-
import type { FallbackFunctionsType, SupportedSchemas } from './types';
|
11
|
-
|
12
|
-
/**
|
13
|
-
* The usage of this is that imagine that the library doesn't support a specific feature that we support on
|
14
|
-
* our schema definition, it can return an instance of this class and with this instance we are able to
|
15
|
-
* fallback to our default implementation of the schema validation.
|
16
|
-
*/
|
17
|
-
export class WithFallback<TType extends SupportedSchemas> {
|
18
|
-
protected $$type = '$PWithFallback';
|
19
|
-
fallbackFor: Set<
|
20
|
-
| keyof Omit<ValidationDataBasedOnType<TType>, 'withFallback' | 'parsers'>
|
21
|
-
| keyof ValidationDataBasedOnType<TType>['parsers']
|
22
|
-
>;
|
23
|
-
transformedSchema: any;
|
24
|
-
adapterType: TType;
|
25
|
-
|
26
|
-
constructor(
|
27
|
-
adapterType: TType,
|
28
|
-
fallbackFor: (
|
29
|
-
| keyof Omit<ValidationDataBasedOnType<TType>, 'withFallback' | 'parsers'>
|
30
|
-
| keyof ValidationDataBasedOnType<TType>['parsers']
|
31
|
-
)[],
|
32
|
-
transformedSchema: any
|
33
|
-
) {
|
34
|
-
this.adapterType = adapterType;
|
35
|
-
this.fallbackFor = new Set<
|
36
|
-
| keyof Omit<ValidationDataBasedOnType<TType>, 'withFallback' | 'parsers'>
|
37
|
-
| keyof ValidationDataBasedOnType<TType>['parsers']
|
38
|
-
>(fallbackFor as any);
|
39
|
-
this.transformedSchema = transformedSchema;
|
40
|
-
}
|
41
|
-
}
|
42
|
-
|
43
|
-
/**
|
44
|
-
* Factory function for creating a new instance of WithFallback. We call that function when parsing the
|
45
|
-
* schema adapter, and then, inside of the adapter the user will can the inner function to create a new
|
46
|
-
* instance of WithFallback.
|
47
|
-
*
|
48
|
-
* @param adapterType - The type of the adapter that we are using.
|
49
|
-
*
|
50
|
-
* @returns - A currying function that will create a new instance of WithFallback.
|
51
|
-
*/
|
52
|
-
export function withFallbackFactory<TType extends SupportedSchemas>(adapterType: TType) {
|
53
|
-
return (
|
54
|
-
fallbackFor: (
|
55
|
-
| keyof Omit<ValidationDataBasedOnType<TType>, 'withFallback' | 'parsers'>
|
56
|
-
| keyof ValidationDataBasedOnType<TType>['parsers']
|
57
|
-
)[],
|
58
|
-
transformedSchema: WithFallback<SupportedSchemas>['transformedSchema']
|
59
|
-
) => new WithFallback<TType>(adapterType, fallbackFor, transformedSchema);
|
60
|
-
}
|
61
|
-
|
62
|
-
export function parseErrorsFactory(schemaAdapter: SchemaAdapter) {
|
63
|
-
return async (
|
64
|
-
errorOrErrors: any | any[],
|
65
|
-
metadata?: any
|
66
|
-
): Promise<Awaited<ReturnType<SchemaAdapter['formatError']>>[]> => {
|
67
|
-
const errorsIsAnArray = Array.isArray(errorOrErrors);
|
68
|
-
if (errorsIsAnArray)
|
69
|
-
return Promise.all(errorOrErrors.map((error) => schemaAdapter.formatError.bind(schemaAdapter)(error, metadata)));
|
70
|
-
return [await schemaAdapter.formatError.bind(schemaAdapter)(errorOrErrors, metadata)];
|
71
|
-
};
|
72
|
-
}
|
73
|
-
|
74
|
-
/**
|
75
|
-
* The default transform function that we use for the schema adapters. This function tries to abstract away
|
76
|
-
* the complexity of translating the schema to the adapter.
|
77
|
-
*
|
78
|
-
* So first things first, WHAT IS a fallback? A fallback is a function that we call when the user defines a
|
79
|
-
* validation that is not supported by the adapter. For example, imagine that for some reason the adapter
|
80
|
-
* doesn't support the `max` validation, we can define a fallback for that validation and then, when the
|
81
|
-
* user defines that validation, we call the fallback function. So, even if the adapter doesn't support that
|
82
|
-
* validation our schema will still be able to validate that.
|
83
|
-
*
|
84
|
-
* @param type - The type of the adapter that we are using, can be a number, an object, all of the possible
|
85
|
-
* schema adapters.
|
86
|
-
* @param schema - The schema that we are translating.
|
87
|
-
* @param validationData - The data that we are using to validate the schema. This means for example, the
|
88
|
-
* `max` validation, the `min` validation, etc. The message of the validation when it is not valid, etc.
|
89
|
-
* @param fallbackFunctions - The fallback functions that we are using to validate the schema. Those are
|
90
|
-
* the functions we fallback to when the user defines a validation that is not supported by the adapter.
|
91
|
-
*
|
92
|
-
* @returns - The translated schema for something that the adapter is able to understand.
|
93
|
-
*/
|
94
|
-
export async function defaultTransform<TType extends SupportedSchemas>(
|
95
|
-
type: TType,
|
96
|
-
schema: Schema<any, any>,
|
97
|
-
adapter: SchemaAdapter,
|
98
|
-
fieldAdapter: FieldAdapter | undefined,
|
99
|
-
getValidationData: (isStringVersion: boolean) => ValidationDataBasedOnType<TType>,
|
100
|
-
fallbackFunctions: FallbackFunctionsType<Omit<Awaited<ReturnType<typeof getValidationData>>, 'parsers'>>,
|
101
|
-
options: {
|
102
|
-
validatorsIfFallbackOrNotSupported?: ValidationFallbackReturnType | ValidationFallbackReturnType[];
|
103
|
-
/**
|
104
|
-
* If the schema is not supported by the adapter, this means, that the adapter hasn't defined an adapter
|
105
|
-
* for that field type, we can fallback to a custom implementation.
|
106
|
-
* The problem is that, for example: Unions,
|
107
|
-
*
|
108
|
-
* Let's say we have a schema like this:
|
109
|
-
* ObjectSchema.new({ age: UnionSchema.new([NumberSchema.new(), StringSchema.new()] )});
|
110
|
-
*
|
111
|
-
* The root object will be validated by the adapter so what we need to do is create two schemas on the
|
112
|
-
* root object, one where the value of `age` key is a number and another where the value of `age` key is
|
113
|
-
* a string. Now the root object has two schemas memoized on __transformedSchemas, nice, what's the logic
|
114
|
-
* on that case? The ObjectSchema shouldn't take care of that logic. So the Union schema takes control of
|
115
|
-
* validating through the adapter. Is adapter 1 without errors? If yes, return the result, if not, try
|
116
|
-
* the second adapter. If the second adapter is without errors, return the result, if not, return the
|
117
|
-
* errors.
|
118
|
-
*
|
119
|
-
* In other words, the `fallbackIfNotSupported` function on Unions should return the two schemas saved on
|
120
|
-
* it on that case, that way the root ObjectSchema will create those two schemas on the array.
|
121
|
-
*/
|
122
|
-
fallbackIfNotSupported?: () => ReturnType<Schema['__transformToAdapter']>;
|
123
|
-
} & Pick<Parameters<Schema['__transformToAdapter']>[0], 'shouldAddStringVersion'>
|
124
|
-
): Promise<any[]> {
|
125
|
-
const validationData = await Promise.resolve(getValidationData(false));
|
126
|
-
|
127
|
-
const validationDataForStringVersion = (
|
128
|
-
options.shouldAddStringVersion ? await Promise.resolve(getValidationData(true)) : undefined
|
129
|
-
) as ValidationDataBasedOnType<TType>;
|
130
|
-
const schemaWithPrivateFields = schema as unknown as {
|
131
|
-
__transformedSchemas: Schema['__transformedSchemas'];
|
132
|
-
__rootFallbacksValidator: Schema['__rootFallbacksValidator'];
|
133
|
-
__optional: Schema['__optional'];
|
134
|
-
__nullable: Schema['__nullable'];
|
135
|
-
__type: Schema['__type'];
|
136
|
-
__parsers: Schema['__parsers'];
|
137
|
-
__extends: Schema['__extends'];
|
138
|
-
};
|
139
|
-
|
140
|
-
const checkIfShouldUseParserAndAppend = (
|
141
|
-
parser: Parameters<WithFallback<SupportedSchemas>['fallbackFor']['add']>[0]
|
142
|
-
) => {
|
143
|
-
const isValidationDataAParser = (validationData as any).parsers?.[parser] !== undefined;
|
144
|
-
if (isValidationDataAParser)
|
145
|
-
(
|
146
|
-
schema as unknown as {
|
147
|
-
__parsers: Schema['__parsers'];
|
148
|
-
}
|
149
|
-
).__parsers._fallbacks.add(parser);
|
150
|
-
};
|
151
|
-
|
152
|
-
const getExtendedOrNotSchemaAndString = (schema: any, toStringVersion: string) => {
|
153
|
-
const extendedOrNotSchema =
|
154
|
-
typeof schemaWithPrivateFields.__extends?.callback === 'function'
|
155
|
-
? schemaWithPrivateFields.__extends.callback(schema)
|
156
|
-
: schema;
|
157
|
-
const extendedOrNotSchemaString =
|
158
|
-
typeof schemaWithPrivateFields.__extends?.toStringCallback === 'function'
|
159
|
-
? schemaWithPrivateFields.__extends.toStringCallback(toStringVersion)
|
160
|
-
: toStringVersion;
|
161
|
-
return [extendedOrNotSchema, extendedOrNotSchemaString];
|
162
|
-
};
|
163
|
-
|
164
|
-
const checkIfShouldAppendFallbackAndAppend = (
|
165
|
-
fallback: Parameters<WithFallback<SupportedSchemas>['fallbackFor']['add']>[0]
|
166
|
-
) => {
|
167
|
-
const wereArgumentsForThatFallbackDefinedAndFallbackFunctionDefined =
|
168
|
-
(validationData as any)[fallback] !== undefined && (fallbackFunctions as any)[fallback] !== undefined;
|
169
|
-
|
170
|
-
if (wereArgumentsForThatFallbackDefinedAndFallbackFunctionDefined) {
|
171
|
-
const fallbackReturnType = (fallbackFunctions as any)[fallback](
|
172
|
-
(validationData as any)[fallback]
|
173
|
-
) as ValidationFallbackReturnType;
|
174
|
-
Validator.createAndAppendFallback(schema, fallbackReturnType);
|
175
|
-
}
|
176
|
-
};
|
177
|
-
|
178
|
-
const appendRootFallback = () => {
|
179
|
-
if (options.validatorsIfFallbackOrNotSupported) {
|
180
|
-
const validatorsIfFallbackOrNotSupported = Array.isArray(options.validatorsIfFallbackOrNotSupported)
|
181
|
-
? options.validatorsIfFallbackOrNotSupported
|
182
|
-
: [options.validatorsIfFallbackOrNotSupported];
|
183
|
-
|
184
|
-
for (const fallback of validatorsIfFallbackOrNotSupported) Validator.createAndAppendFallback(schema, fallback);
|
185
|
-
}
|
186
|
-
};
|
187
|
-
|
188
|
-
const appendRequiredFallbacks = () => {
|
189
|
-
// eslint-disable-next-line ts/no-unnecessary-condition
|
190
|
-
const hasFallbacks = schemaWithPrivateFields.__rootFallbacksValidator?.['$$type'] === '$PValidator';
|
191
|
-
if (hasFallbacks) {
|
192
|
-
Validator.createAndAppendFallback(schema, optional(schemaWithPrivateFields.__optional));
|
193
|
-
Validator.createAndAppendFallback(schema, nullable(schemaWithPrivateFields.__nullable));
|
194
|
-
Validator.createAndAppendFallback(schema, checkType(schemaWithPrivateFields.__type));
|
195
|
-
}
|
196
|
-
};
|
197
|
-
|
198
|
-
const isFieldAdapterNotSupportedForThatFieldType = fieldAdapter === undefined;
|
199
|
-
|
200
|
-
if (options.fallbackIfNotSupported !== undefined && isFieldAdapterNotSupportedForThatFieldType) {
|
201
|
-
const existingFallbacks = Object.keys(fallbackFunctions) as Parameters<
|
202
|
-
WithFallback<SupportedSchemas>['fallbackFor']['add']
|
203
|
-
>[0][];
|
204
|
-
const allParsers = Object.keys(validationData['parsers']) as Parameters<
|
205
|
-
WithFallback<SupportedSchemas>['fallbackFor']['add']
|
206
|
-
>[0][];
|
207
|
-
|
208
|
-
appendRootFallback();
|
209
|
-
|
210
|
-
for (const fallback of existingFallbacks) checkIfShouldAppendFallbackAndAppend(fallback);
|
211
|
-
for (const parser of allParsers) checkIfShouldUseParserAndAppend(parser);
|
212
|
-
appendRequiredFallbacks();
|
213
|
-
|
214
|
-
return options.fallbackIfNotSupported();
|
215
|
-
}
|
216
|
-
if (!fieldAdapter) throw new Error('The field adapter is not supported and no fallback was provided.');
|
217
|
-
|
218
|
-
const translatedSchemaOrWithFallback = await Promise.resolve(
|
219
|
-
fieldAdapter.translate(adapter.field, {
|
220
|
-
withFallback: withFallbackFactory<SupportedSchemas>(type),
|
221
|
-
...validationData
|
222
|
-
})
|
223
|
-
);
|
224
|
-
|
225
|
-
let stringVersion = '';
|
226
|
-
if (options.shouldAddStringVersion)
|
227
|
-
stringVersion = await fieldAdapter.toString(adapter, adapter.field, validationDataForStringVersion);
|
228
|
-
|
229
|
-
// eslint-disable-next-line ts/no-unnecessary-condition
|
230
|
-
if ((translatedSchemaOrWithFallback as WithFallback<any>)?.['$$type'] === '$PWithFallback') {
|
231
|
-
appendRootFallback();
|
232
|
-
for (const fallback of translatedSchemaOrWithFallback.fallbackFor) {
|
233
|
-
checkIfShouldAppendFallbackAndAppend(fallback);
|
234
|
-
checkIfShouldUseParserAndAppend(fallback);
|
235
|
-
}
|
236
|
-
|
237
|
-
const [extendedOrNotSchema, extendedOrNotSchemaString] = getExtendedOrNotSchemaAndString(
|
238
|
-
translatedSchemaOrWithFallback.transformedSchema,
|
239
|
-
stringVersion
|
240
|
-
);
|
241
|
-
appendRequiredFallbacks();
|
242
|
-
|
243
|
-
return [
|
244
|
-
{
|
245
|
-
transformed: extendedOrNotSchema,
|
246
|
-
asString: extendedOrNotSchemaString
|
247
|
-
}
|
248
|
-
];
|
249
|
-
}
|
250
|
-
|
251
|
-
const [extendedOrNotSchema, extendedOrNotSchemaString] = getExtendedOrNotSchemaAndString(
|
252
|
-
translatedSchemaOrWithFallback,
|
253
|
-
stringVersion
|
254
|
-
);
|
255
|
-
|
256
|
-
return [
|
257
|
-
{
|
258
|
-
transformed: extendedOrNotSchema,
|
259
|
-
asString: extendedOrNotSchemaString
|
260
|
-
}
|
261
|
-
];
|
262
|
-
}
|
263
|
-
|
264
|
-
/**
|
265
|
-
* This function is used to transform the schema to the adapter. By default it caches the transformed schemas on
|
266
|
-
* the schema instance. So on subsequent validations we don't need to transform to the schema again.
|
267
|
-
*/
|
268
|
-
export async function defaultTransformToAdapter(
|
269
|
-
callback: (adapter: SchemaAdapter) => ReturnType<FieldAdapter['translate']>,
|
270
|
-
schema: Schema<any, any>,
|
271
|
-
transformedSchemas: Schema['__transformedSchemas'],
|
272
|
-
options: Parameters<Schema['__transformToAdapter']>[0],
|
273
|
-
type: string
|
274
|
-
) {
|
275
|
-
const isTransformedSchemasEmpty = Object.keys(transformedSchemas).length <= 0;
|
276
|
-
if (isTransformedSchemasEmpty) {
|
277
|
-
const adapterInstanceToUse =
|
278
|
-
// eslint-disable-next-line ts/no-unnecessary-condition
|
279
|
-
(options.schemaAdapter as SchemaAdapter)?.['$$type'] === '$PSchemaAdapter'
|
280
|
-
? options.schemaAdapter
|
281
|
-
: getDefaultAdapter();
|
282
|
-
schema['__transformedSchemas'][(adapterInstanceToUse as SchemaAdapter).name] = {
|
283
|
-
transformed: false,
|
284
|
-
adapter: adapterInstanceToUse,
|
285
|
-
schemas: []
|
286
|
-
};
|
287
|
-
}
|
288
|
-
|
289
|
-
const schemaAdapterNameToUse = options.schemaAdapter?.name || Object.keys(transformedSchemas)[0];
|
290
|
-
const isACustomSchemaAdapterAndNotYetDefined =
|
291
|
-
// eslint-disable-next-line ts/no-unnecessary-condition
|
292
|
-
transformedSchemas[schemaAdapterNameToUse] === undefined && options.schemaAdapter !== undefined;
|
293
|
-
|
294
|
-
if (isACustomSchemaAdapterAndNotYetDefined)
|
295
|
-
transformedSchemas[schemaAdapterNameToUse] = {
|
296
|
-
transformed: false,
|
297
|
-
adapter: options.schemaAdapter as SchemaAdapter,
|
298
|
-
schemas: []
|
299
|
-
};
|
300
|
-
|
301
|
-
const shouldTranslate = transformedSchemas[schemaAdapterNameToUse].transformed === false || options.force === true;
|
302
|
-
|
303
|
-
if (shouldTranslate) {
|
304
|
-
const translatedSchemas = await callback(transformedSchemas[schemaAdapterNameToUse].adapter);
|
305
|
-
transformedSchemas[schemaAdapterNameToUse].schemas = translatedSchemas;
|
306
|
-
transformedSchemas[schemaAdapterNameToUse].transformed = true;
|
307
|
-
}
|
308
|
-
transformedSchemas[schemaAdapterNameToUse].transformed = true;
|
309
|
-
|
310
|
-
return transformedSchemas[schemaAdapterNameToUse].schemas;
|
311
|
-
}
|
312
|
-
|
313
|
-
export async function formatErrorFromParseMethod(
|
314
|
-
adapter: SchemaAdapter,
|
315
|
-
fieldAdapter: FieldAdapter,
|
316
|
-
error: any,
|
317
|
-
received: any,
|
318
|
-
schema: any,
|
319
|
-
path: ValidationFallbackCallbackReturnType['errors'][number]['path'],
|
320
|
-
errorsAsHashedSet: Set<string>
|
321
|
-
) {
|
322
|
-
const formattedError = await fieldAdapter.formatError(adapter, adapter.field, schema, error);
|
323
|
-
formattedError.path = Array.isArray(formattedError.path) ? [...path, ...formattedError.path] : path;
|
324
|
-
|
325
|
-
const formattedErrorAsParseResultError =
|
326
|
-
formattedError as unknown as ValidationFallbackCallbackReturnType['errors'][number];
|
327
|
-
formattedErrorAsParseResultError.isValid = false;
|
328
|
-
const sortedError = Object.fromEntries(
|
329
|
-
Object.entries(formattedErrorAsParseResultError).sort(([a], [b]) => a.localeCompare(b))
|
330
|
-
);
|
331
|
-
const hashedError = JSON.stringify(sortedError);
|
332
|
-
errorsAsHashedSet.add(JSON.stringify(sortedError));
|
333
|
-
formattedErrorAsParseResultError.received = received;
|
334
|
-
return formattedErrorAsParseResultError;
|
335
|
-
}
|
336
|
-
|
337
|
-
/**
|
338
|
-
* Transform the schema and check if we should add a fallback validation for that schema. This is used for complex
|
339
|
-
* schemas like Objects, arrays, unions, etc.
|
340
|
-
*/
|
341
|
-
export async function transformSchemaAndCheckIfShouldBeHandledByFallbackOnComplexSchemas(
|
342
|
-
schema: Schema,
|
343
|
-
options: Parameters<Schema['__transformToAdapter']>[0]
|
344
|
-
) {
|
345
|
-
const schemaWithProtected = schema as Schema & {
|
346
|
-
__runBeforeParseAndData: Schema['__runBeforeParseAndData'];
|
347
|
-
__toInternal: Schema['__toInternal'];
|
348
|
-
__toValidate: Schema['__toValidate'];
|
349
|
-
__toRepresentation: Schema['__toRepresentation'];
|
350
|
-
__defaultFunction: Schema['__defaultFunction'];
|
351
|
-
__rootFallbacksValidator: Schema['__rootFallbacksValidator'];
|
352
|
-
__transformToAdapter: Schema['__transformToAdapter'];
|
353
|
-
__parsers: Schema['__parsers'];
|
354
|
-
};
|
355
|
-
|
356
|
-
// This should come first because we will get the fallbacks of the field here.
|
357
|
-
const transformedData = await schemaWithProtected.__transformToAdapter(options);
|
358
|
-
|
359
|
-
// eslint-disable-next-line ts/no-unnecessary-condition
|
360
|
-
const doesKeyHaveFallback = schemaWithProtected.__rootFallbacksValidator !== undefined;
|
361
|
-
const doesKeyHaveToInternal = typeof schemaWithProtected.__toInternal === 'function';
|
362
|
-
const doesKeyHaveToValidate = typeof schemaWithProtected.__toValidate === 'function';
|
363
|
-
const doesKeyHaveToDefault = typeof schemaWithProtected.__defaultFunction === 'function';
|
364
|
-
const doesKeyHaveRunBeforeParseAndData = typeof schemaWithProtected.__runBeforeParseAndData === 'function';
|
365
|
-
const doesKeyHaveParserFallback = schemaWithProtected.__parsers._fallbacks.size > 0;
|
366
|
-
const shouldAddFallbackValidation =
|
367
|
-
doesKeyHaveFallback ||
|
368
|
-
doesKeyHaveToInternal ||
|
369
|
-
doesKeyHaveToValidate ||
|
370
|
-
doesKeyHaveToDefault ||
|
371
|
-
doesKeyHaveParserFallback ||
|
372
|
-
doesKeyHaveRunBeforeParseAndData ||
|
373
|
-
// eslint-disable-next-line ts/no-unnecessary-condition
|
374
|
-
transformedData === undefined;
|
375
|
-
|
376
|
-
return [transformedData, shouldAddFallbackValidation] as const;
|
377
|
-
}
|
378
|
-
|
379
|
-
export function shouldRunDataOnComplexSchemas(schema: Schema<any, any>) {
|
380
|
-
return (
|
381
|
-
schema['__parsers'].high.size > 0 ||
|
382
|
-
schema['__parsers'].medium.size > 0 ||
|
383
|
-
schema['__parsers'].low.size > 0 ||
|
384
|
-
schema['__parsers']._fallbacks.size > 0 ||
|
385
|
-
typeof schema['__runBeforeParseAndData'] === 'function' ||
|
386
|
-
typeof schema['__toRepresentation'] === 'function' ||
|
387
|
-
typeof schema['__defaultFunction'] === 'function'
|
388
|
-
);
|
389
|
-
}
|
package/src/validators/array.ts
DELETED
@@ -1,183 +0,0 @@
|
|
1
|
-
import type { ArraySchema } from '../schema/array';
|
2
|
-
import type { Schema } from '../schema/schema';
|
3
|
-
import type { ValidationFallbackCallbackReturnType, ValidationFallbackReturnType } from '../schema/types';
|
4
|
-
|
5
|
-
export function arrayValidation(isTuple: boolean, schemas: Schema<any, any>[]): ValidationFallbackReturnType {
|
6
|
-
return {
|
7
|
-
name: 'array',
|
8
|
-
type: 'medium',
|
9
|
-
callback: async (value: any, path: (string | number)[], options: Parameters<Schema['__transformToAdapter']>[0]) => {
|
10
|
-
const isNotAnArray = Array.isArray(value) === false;
|
11
|
-
if (isNotAnArray)
|
12
|
-
return {
|
13
|
-
parsed: value,
|
14
|
-
preventChildValidation: true,
|
15
|
-
errors: [
|
16
|
-
{
|
17
|
-
isValid: false,
|
18
|
-
code: 'array',
|
19
|
-
// eslint-disable-next-line ts/no-unnecessary-condition
|
20
|
-
path: path || [],
|
21
|
-
message: 'The value must be an array. Received: ' + typeof value
|
22
|
-
}
|
23
|
-
]
|
24
|
-
};
|
25
|
-
if (isTuple && value.length !== schemas.length)
|
26
|
-
return {
|
27
|
-
parsed: value,
|
28
|
-
preventChildValidation: true,
|
29
|
-
errors: [
|
30
|
-
{
|
31
|
-
isValid: false,
|
32
|
-
code: 'tuple',
|
33
|
-
// eslint-disable-next-line ts/no-unnecessary-condition
|
34
|
-
path: path || [],
|
35
|
-
message: 'The tuple must have exactly ' + schemas.length + ' elements. Received: ' + value.length
|
36
|
-
}
|
37
|
-
]
|
38
|
-
};
|
39
|
-
|
40
|
-
const errorsOfArray: ValidationFallbackCallbackReturnType['errors'] = [];
|
41
|
-
|
42
|
-
// To speed things up, we can do a simple type check, if the value is of type number and
|
43
|
-
// number is on index 1, and on index 0 is a string,
|
44
|
-
// if the value is a number we can skip checking at index 0.
|
45
|
-
const schemaIndexByTypeof = new Map<string, number>();
|
46
|
-
let parsedValues: any[] = [];
|
47
|
-
parsedValues = await Promise.all(
|
48
|
-
value.map(async (element, index) => {
|
49
|
-
let errorsToAppendAfterLoopIfNoSchemaMatched: ValidationFallbackCallbackReturnType['errors'] = [];
|
50
|
-
const typeofElement = typeof element;
|
51
|
-
const schemaIndex = schemaIndexByTypeof.get(typeofElement);
|
52
|
-
const existsASchemaIndex = typeof schemaIndex === 'number';
|
53
|
-
|
54
|
-
const schemasToValidateAgainst = isTuple
|
55
|
-
? [schemas[index]]
|
56
|
-
: existsASchemaIndex
|
57
|
-
? [schemas[schemaIndex]]
|
58
|
-
: schemas;
|
59
|
-
|
60
|
-
for (let indexOfSchema = 0; indexOfSchema < schemasToValidateAgainst.length; indexOfSchema++) {
|
61
|
-
const schemaToValidate = schemasToValidateAgainst[indexOfSchema];
|
62
|
-
const schemaWithProtected = schemaToValidate as Schema & {
|
63
|
-
__parse: Schema['__parse'];
|
64
|
-
__toInternal: Schema['__toInternal'];
|
65
|
-
};
|
66
|
-
const { parsed, errors } = await schemaWithProtected.__parse(element, [...path, index], options);
|
67
|
-
|
68
|
-
if (schemaWithProtected.__toInternal && options.toInternalToBubbleUp)
|
69
|
-
options.toInternalToBubbleUp.push(
|
70
|
-
async () => (parsedValues[indexOfSchema] = await schemaWithProtected.__toInternal?.(parsed))
|
71
|
-
);
|
72
|
-
|
73
|
-
// eslint-disable-next-line ts/no-unnecessary-condition
|
74
|
-
if ((errors || []).length <= 0) {
|
75
|
-
errorsToAppendAfterLoopIfNoSchemaMatched = [];
|
76
|
-
schemaIndexByTypeof.set(typeofElement, indexOfSchema);
|
77
|
-
return parsed;
|
78
|
-
}
|
79
|
-
errorsToAppendAfterLoopIfNoSchemaMatched.push(...errors);
|
80
|
-
}
|
81
|
-
|
82
|
-
errorsOfArray.push(...errorsToAppendAfterLoopIfNoSchemaMatched);
|
83
|
-
return element;
|
84
|
-
})
|
85
|
-
);
|
86
|
-
|
87
|
-
return {
|
88
|
-
parsed: parsedValues,
|
89
|
-
errors: errorsOfArray
|
90
|
-
};
|
91
|
-
}
|
92
|
-
};
|
93
|
-
}
|
94
|
-
|
95
|
-
export function minLength(args: ArraySchema['__minLength']): ValidationFallbackReturnType {
|
96
|
-
return {
|
97
|
-
name: 'minLength',
|
98
|
-
type: 'low',
|
99
|
-
// eslint-disable-next-line ts/require-await
|
100
|
-
callback: async (
|
101
|
-
value: any,
|
102
|
-
path: (string | number)[],
|
103
|
-
_options: Parameters<Schema['__transformToAdapter']>[0]
|
104
|
-
) => {
|
105
|
-
const isValid = args.inclusive ? value.length >= args.value : value.length > args.value;
|
106
|
-
|
107
|
-
return {
|
108
|
-
parsed: value,
|
109
|
-
errors: isValid
|
110
|
-
? []
|
111
|
-
: [
|
112
|
-
{
|
113
|
-
isValid: false,
|
114
|
-
code: 'minLength',
|
115
|
-
// eslint-disable-next-line ts/no-unnecessary-condition
|
116
|
-
path: path || [],
|
117
|
-
message: args.message
|
118
|
-
}
|
119
|
-
]
|
120
|
-
};
|
121
|
-
}
|
122
|
-
};
|
123
|
-
}
|
124
|
-
|
125
|
-
export function maxLength(args: ArraySchema['__maxLength']): ValidationFallbackReturnType {
|
126
|
-
return {
|
127
|
-
name: 'maxLength',
|
128
|
-
type: 'low',
|
129
|
-
// eslint-disable-next-line ts/require-await
|
130
|
-
callback: async (
|
131
|
-
value: any,
|
132
|
-
path: (string | number)[],
|
133
|
-
_options: Parameters<Schema['__transformToAdapter']>[0]
|
134
|
-
) => {
|
135
|
-
const isValid = args.inclusive ? value.length <= args.value : value.length < args.value;
|
136
|
-
|
137
|
-
return {
|
138
|
-
parsed: value,
|
139
|
-
errors: isValid
|
140
|
-
? []
|
141
|
-
: [
|
142
|
-
{
|
143
|
-
isValid: false,
|
144
|
-
code: 'maxLength',
|
145
|
-
// eslint-disable-next-line ts/no-unnecessary-condition
|
146
|
-
path: path || [],
|
147
|
-
message: args.message
|
148
|
-
}
|
149
|
-
]
|
150
|
-
};
|
151
|
-
}
|
152
|
-
};
|
153
|
-
}
|
154
|
-
|
155
|
-
export function nonEmpty(args: ArraySchema['__nonEmpty']): ValidationFallbackReturnType {
|
156
|
-
return {
|
157
|
-
name: 'nonEmpty',
|
158
|
-
type: 'low',
|
159
|
-
// eslint-disable-next-line ts/require-await
|
160
|
-
callback: async (
|
161
|
-
value: any,
|
162
|
-
path: (string | number)[],
|
163
|
-
_options: Parameters<Schema['__transformToAdapter']>[0]
|
164
|
-
) => {
|
165
|
-
const isValid = value.length > 0;
|
166
|
-
|
167
|
-
return {
|
168
|
-
parsed: value,
|
169
|
-
errors: isValid
|
170
|
-
? []
|
171
|
-
: [
|
172
|
-
{
|
173
|
-
isValid: false,
|
174
|
-
code: 'nonEmpty',
|
175
|
-
// eslint-disable-next-line ts/no-unnecessary-condition
|
176
|
-
path: path || [],
|
177
|
-
message: args.message
|
178
|
-
}
|
179
|
-
]
|
180
|
-
};
|
181
|
-
}
|
182
|
-
};
|
183
|
-
}
|
@@ -1,52 +0,0 @@
|
|
1
|
-
import type { Schema } from '../schema/schema';
|
2
|
-
import type { ValidationFallbackReturnType } from '../schema/types';
|
3
|
-
|
4
|
-
export function booleanValidation(): ValidationFallbackReturnType {
|
5
|
-
return {
|
6
|
-
name: 'boolean',
|
7
|
-
type: 'medium',
|
8
|
-
// eslint-disable-next-line ts/require-await
|
9
|
-
callback: async (
|
10
|
-
value: any,
|
11
|
-
path: (string | number)[],
|
12
|
-
_options: Parameters<Schema['__transformToAdapter']>[0]
|
13
|
-
) => {
|
14
|
-
const isValid = typeof value === 'boolean';
|
15
|
-
|
16
|
-
return {
|
17
|
-
parsed: value,
|
18
|
-
errors: isValid
|
19
|
-
? []
|
20
|
-
: [
|
21
|
-
{
|
22
|
-
isValid: false,
|
23
|
-
code: 'boolean',
|
24
|
-
// eslint-disable-next-line ts/no-unnecessary-condition
|
25
|
-
path: path || [],
|
26
|
-
message: 'Value is not a boolean'
|
27
|
-
}
|
28
|
-
],
|
29
|
-
preventChildValidation: true
|
30
|
-
};
|
31
|
-
}
|
32
|
-
};
|
33
|
-
}
|
34
|
-
|
35
|
-
export function allowStringParser(): ValidationFallbackReturnType {
|
36
|
-
return {
|
37
|
-
name: 'allowString',
|
38
|
-
type: 'high',
|
39
|
-
// eslint-disable-next-line ts/require-await
|
40
|
-
callback: async (
|
41
|
-
value: any,
|
42
|
-
_path: (string | number)[],
|
43
|
-
_options: Parameters<Schema['__transformToAdapter']>[0]
|
44
|
-
) => {
|
45
|
-
const parsed = Boolean(value);
|
46
|
-
return {
|
47
|
-
parsed: parsed,
|
48
|
-
errors: []
|
49
|
-
};
|
50
|
-
}
|
51
|
-
};
|
52
|
-
}
|