@cleverbrush/schema 1.0.0 → 1.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.
@@ -83,7 +83,9 @@ export declare class DateSchemaBuilder<TResult = Date, TRequired extends boolean
83
83
  * Array of validator functions
84
84
  */
85
85
  validators: Validator<TResult>[];
86
- type: string;
86
+ type: string; /**
87
+ * @hidden
88
+ */
87
89
  isRequired: boolean;
88
90
  };
89
91
  /**
@@ -1,19 +1,29 @@
1
1
  import { InferType, SchemaBuilder, ValidationContext, ValidationResult } from './SchemaBuilder.js';
2
2
  type ObjectSchemaBuilderProps<T extends Record<string, SchemaBuilder> = {}, TRequired extends boolean = true> = ReturnType<ObjectSchemaBuilder<T, TRequired>['introspect']>;
3
3
  type ObjectSchemaBuilderCreateProps<T extends Record<string, SchemaBuilder> = {}, TRequired extends boolean = true> = Partial<ObjectSchemaBuilderProps<T, TRequired>>;
4
- type RequiredPropertyNames<T> = {
5
- [K in keyof T]-?: undefined extends T[K] ? never : K;
6
- }[keyof T];
7
- type OptionalPropertyNames<T> = {
8
- [K in keyof T]-?: undefined extends T[K] ? K : never;
9
- }[keyof T];
10
- type SpreadProperties<L, R, K extends keyof L & keyof R> = {
11
- [P in K]: L[P] | Exclude<R[P], undefined>;
12
- };
13
4
  type Id<T> = T extends infer U ? {
14
5
  [K in keyof U]: U[K];
15
6
  } : never;
16
- type MergeTwo<L, R> = Id<Pick<L, Exclude<keyof L, keyof R>> & Pick<R, Exclude<keyof R, OptionalPropertyNames<R>>> & Pick<R, Exclude<OptionalPropertyNames<R>, keyof L>> & SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>>;
7
+ export type RespectPropsOptionality<T extends Record<string, SchemaBuilder<any, any>>> = {
8
+ [K in RequiredProps<T>]: InferType<T[K]>;
9
+ } & {
10
+ [K in NotRequiredProps<T>]?: InferType<T[K]>;
11
+ };
12
+ type MakeChildrenRequired<T extends Record<string, SchemaBuilder<any, any>>> = {
13
+ [K in keyof T]: ReturnType<T[K]['required']>;
14
+ };
15
+ type MakeChildrenOptional<T extends Record<string, SchemaBuilder<any, any>>> = {
16
+ [K in keyof T]: ReturnType<T[K]['optional']>;
17
+ };
18
+ type MakeChildOptional<T extends Record<any, SchemaBuilder<any, any>>, TProp extends keyof T> = {
19
+ [K in keyof T]: K extends TProp ? ReturnType<T[K]['optional']> : T[K];
20
+ };
21
+ type MakeChildRequired<T extends Record<any, SchemaBuilder<any, any>>, TProp extends keyof T> = {
22
+ [K in keyof T]: K extends TProp ? ReturnType<T[K]['required']> : T[K];
23
+ };
24
+ type ModifyPropSchema<T extends Record<any, SchemaBuilder<any, any>>, TProp extends keyof T, TSchema extends SchemaBuilder<any, any>> = {
25
+ [K in keyof T]: K extends TProp ? TSchema : T[K];
26
+ };
17
27
  /**
18
28
  * Object schema builder class. Similar to the `object` type
19
29
  * in JS. Allows to define a schema for `object` value.
@@ -99,9 +109,9 @@ type MergeTwo<L, R> = Id<Pick<L, Exclude<keyof L, keyof R>> & Pick<R, Exclude<ke
99
109
  * ```
100
110
  * @see {@link object}
101
111
  */
102
- export declare class ObjectSchemaBuilder<TProperties extends Record<string, SchemaBuilder<any, any>> = {}, TRequired extends boolean = true, TExplicitType = undefined, TResult = {}, TFinalResult = undefined extends TExplicitType ? TResult : TExplicitType> extends SchemaBuilder<TFinalResult, TRequired> {
112
+ export declare class ObjectSchemaBuilder<TProperties extends Record<string, SchemaBuilder<any, any>> = {}, TRequired extends boolean = true, TExplicitType = undefined> extends SchemaBuilder<undefined extends TExplicitType ? RespectPropsOptionality<TProperties> : TExplicitType, TRequired> {
103
113
  #private;
104
- static create<P extends Record<string, SchemaBuilder>, R extends boolean>(props: ObjectSchemaBuilderCreateProps<P, R>): ObjectSchemaBuilder<{}, true, undefined, {}, {}>;
114
+ static create<P extends Record<string, SchemaBuilder>, R extends boolean>(props: ObjectSchemaBuilderCreateProps<P, R>): ObjectSchemaBuilder<{}, true, undefined>;
105
115
  protected createFromProps<T extends Record<string, SchemaBuilder>, R extends boolean = true>(props: ObjectSchemaBuilderCreateProps<T, R>): this;
106
116
  private constructor();
107
117
  introspect(): {
@@ -118,48 +128,40 @@ export declare class ObjectSchemaBuilder<TProperties extends Record<string, Sche
118
128
  acceptUnknownProps: boolean;
119
129
  type: string;
120
130
  isRequired: boolean;
121
- preprocessors: readonly import("./SchemaBuilder.js").Preprocessor<TFinalResult>[];
122
- validators: readonly import("./SchemaBuilder.js").Validator<TFinalResult>[];
131
+ preprocessors: readonly import("./SchemaBuilder.js").Preprocessor<undefined extends TExplicitType ? RespectPropsOptionality<TProperties> : TExplicitType>[];
132
+ validators: readonly import("./SchemaBuilder.js").Validator<undefined extends TExplicitType ? RespectPropsOptionality<TProperties> : TExplicitType>[];
123
133
  };
124
134
  /**
125
135
  * @hidden
126
136
  */
127
- required(): ObjectSchemaBuilder<TProperties, true, TExplicitType, TResult>;
137
+ required(): ObjectSchemaBuilder<TProperties, true, TExplicitType>;
128
138
  /**
129
139
  * @hidden
130
140
  */
131
- optional(): ObjectSchemaBuilder<TProperties, false, TExplicitType, TResult>;
141
+ optional(): ObjectSchemaBuilder<TProperties, false, TExplicitType>;
132
142
  /**
133
143
  * Performs validion of object schema over the `object`.
134
144
  * @param context Optional `ValidationContext` settings.
135
145
  */
136
- validate(object: InferType<SchemaBuilder<undefined extends TExplicitType ? MergeTwo<Omit<{
137
- [k in keyof TResult]?: k extends OptionalPropertyNames<TResult> ? TResult[k] : never;
138
- }, RequiredPropertyNames<TResult>>, Omit<{
139
- [k in keyof TResult]: k extends OptionalPropertyNames<TResult> ? never : TResult[k];
140
- }, OptionalPropertyNames<TResult>>> : TResult, TRequired>>, context?: ValidationContext): Promise<ValidationResult<InferType<SchemaBuilder<undefined extends TExplicitType ? MergeTwo<Omit<{
141
- [k in keyof TResult]?: k extends OptionalPropertyNames<TResult> ? TResult[k] : never;
142
- }, RequiredPropertyNames<TResult>>, Omit<{
143
- [k in keyof TResult]: k extends OptionalPropertyNames<TResult> ? never : TResult[k];
144
- }, OptionalPropertyNames<TResult>>> : TResult, TRequired>>>>;
146
+ validate(object: undefined extends TExplicitType ? RespectPropsOptionality<TProperties> : TExplicitType, context?: ValidationContext): Promise<ValidationResult<undefined extends TExplicitType ? RespectPropsOptionality<TProperties> : TExplicitType>>;
145
147
  /**
146
148
  * Fields not defined in `properties` will not be validated
147
149
  * and will be passed through the validation.
148
150
  */
149
- acceptUnknownProps(): ObjectSchemaBuilder<TProperties, TRequired, TExplicitType, TResult>;
151
+ acceptUnknownProps(): ObjectSchemaBuilder<TProperties, TRequired, TExplicitType>;
150
152
  /**
151
153
  * Fields not defined in `properties` will be considered
152
154
  * as schema violation. This is the default behavior.
153
155
  */
154
- notAcceptUnknownProps(): ObjectSchemaBuilder<TProperties, TRequired, TExplicitType, TResult>;
156
+ notAcceptUnknownProps(): ObjectSchemaBuilder<TProperties, TRequired, TExplicitType>;
155
157
  /**
156
158
  * @hidden
157
159
  */
158
- hasType<T>(notUsed?: T): ObjectSchemaBuilder<TProperties, TRequired, T, TResult>;
160
+ hasType<T>(notUsed?: T): ObjectSchemaBuilder<TProperties, TRequired, T>;
159
161
  /**
160
162
  * @hidden
161
163
  */
162
- clearHasType(): ObjectSchemaBuilder<TProperties, TRequired, undefined, TResult>;
164
+ clearHasType(): ObjectSchemaBuilder<TProperties, TRequired>;
163
165
  /**
164
166
  * Adds a new property to the object schema. The new property
165
167
  * will be validated according to the provided schema.
@@ -168,124 +170,97 @@ export declare class ObjectSchemaBuilder<TProperties extends Record<string, Sche
168
170
  */
169
171
  addProp<TType extends SchemaBuilder<any, any>, TName extends string>(propName: TName, schema: TType): ObjectSchemaBuilder<TProperties & {
170
172
  [k in TName]: TType;
171
- }, TRequired, TExplicitType, TResult & (TType extends SchemaBuilder<infer K, infer TR> ? TR extends false ? {
172
- [k in TName]?: InferType<TType>;
173
- } : {
174
- [k in TName]: InferType<TType>;
175
- } : never)>;
173
+ }, TRequired, TExplicitType>;
176
174
  /**
177
175
  * @hidden
178
176
  * @deprecated this is for internal use, do not use if you are
179
177
  * not sure you need it.
178
+ *
179
+ * TODO: This is used to avoid `&` in resulting types. For example,
180
+ * when you have a schema like `object({prop1: string()})` and then use `addProp({prop2: string()})` method,
181
+ * the resulting type without `optimize` will be something like `{prop1: string} & {prop2: string}`. Which
182
+ * is not we would like to have. Instead we want to have `{prop1: string, prop2: string}`. This is what
183
+ * `optimize` method does. However it is not always possible to do this optimization without losing
184
+ * JSDoc comments, which is sucks. For example, I had to disable optimization for UnionSchemas, because
185
+ * comments were lost. Hopefully it will be fixed in the future by Typescript team or somebody will
186
+ * find a workaround/fix and create a pull request.
180
187
  */
181
- optimize(): ObjectSchemaBuilder<TProperties, TRequired, TExplicitType, undefined extends TExplicitType ? MergeTwo<Omit<{
182
- [k in keyof TResult]?: k extends OptionalPropertyNames<TResult> ? TResult[k] : never;
183
- }, RequiredPropertyNames<TResult>>, Omit<{
184
- [k in keyof TResult]: k extends OptionalPropertyNames<TResult> ? never : TResult[k];
185
- }, OptionalPropertyNames<TResult>>> : TResult>;
188
+ optimize(): SchemaBuilder<undefined extends TExplicitType ? Id<RespectPropsOptionality<TProperties>> : TExplicitType>;
186
189
  /**
187
190
  * Adds new properties to the object schema. The same as `.addProp()` but
188
191
  * allows to add multiple properties with one call. The new properties
189
192
  * will be validated according to the provided schemas.
190
193
  * @param props a key/schema object map.
191
194
  */
192
- addProps<TProps extends Record<string, SchemaBuilder<any, any>>, TOptProps = Pick<TProps, keyof {
193
- [k in keyof TProps as TProps[k] extends SchemaBuilder<any, infer TReq> ? TReq extends false ? k : never : never]: TProps[k];
194
- }>, TReqProps = Pick<TProps, keyof {
195
- [k in keyof TProps as TProps[k] extends SchemaBuilder<any, infer TReq> ? TReq extends true ? k : never : never]: TProps[k];
196
- }>>(props: TProps): ObjectSchemaBuilder<TProperties & {
197
- [k in keyof TProps]: TProps[k];
198
- }, true, undefined, TResult & {
199
- [k in keyof TOptProps]?: InferType<TOptProps[k]>;
200
- } & {
201
- [k in keyof TReqProps]: InferType<TReqProps[k]>;
202
- }>;
195
+ addProps<TProps extends Record<string, SchemaBuilder<any, any>>>(props: TProps): ObjectSchemaBuilder<TProperties & TProps, true, undefined>;
203
196
  /**
204
197
  * Adds all properties from the `schema` object schema to the current schema.
205
198
  * @param schema an instance of `ObjectSchemaBuilder`
206
199
  */
207
- addProps<K extends ObjectSchemaBuilder<any, any, any, any>>(schema: K): K extends ObjectSchemaBuilder<infer TProp, infer TReq, infer TExpType, infer TRes> ? ObjectSchemaBuilder<Omit<TProperties, keyof TProp> & {
208
- [k in keyof TProp]: TProp[k];
209
- }, TRequired, TExplicitType, Omit<TResult, keyof TRes> & Omit<TRes, keyof TResult>> : never;
200
+ addProps<K extends ObjectSchemaBuilder<any, any, any>>(schema: K): K extends ObjectSchemaBuilder<infer TProp, infer TReq, infer TExpType> ? ObjectSchemaBuilder<Omit<TProperties, keyof TProp> & TProp, TRequired, TExplicitType> : never;
210
201
  /**
211
202
  * Omits properties listed in `properties` from the schema.
212
203
  * Consider `Omit<Type, 'prop1'|'prop2'...>` as a good illustration
213
204
  * from the TS world.
214
205
  * @param properties - array of property names (strings) to remove from the schema.
215
206
  */
216
- omit<K extends keyof TProperties>(properties: K[]): ObjectSchemaBuilder<Omit<TProperties, K>, TRequired, TExplicitType, Omit<TResult, K>>;
207
+ omit<K extends keyof TProperties>(properties: K[]): ObjectSchemaBuilder<Omit<TProperties, K>, TRequired, TExplicitType>;
217
208
  /**
218
209
  * Removes `propName` from the list of properties.
219
210
  * @param propName property name to remove. Schema should contain
220
211
  * this property. An error will be thrown otherwise.
221
212
  */
222
- omit<TProperty extends keyof TProperties>(propName: TProperty): ObjectSchemaBuilder<Omit<TProperties, TProperty>, TRequired, TExplicitType, Omit<TResult, TProperty>>;
213
+ omit<TProperty extends keyof TProperties>(propName: TProperty): ObjectSchemaBuilder<Omit<TProperties, TProperty>, TRequired, TExplicitType>;
223
214
  /**
224
215
  * Removes all properties of `schema` from the current schema.
225
216
  * `Omit<TSchema, keyof TAnotherSchema>` as a good illustration
226
217
  * from the TS world.
227
218
  * @param schema schema builder to take properties from.
228
219
  */
229
- omit<T>(schema: T): T extends ObjectSchemaBuilder<infer TProps, infer TRequired, infer TExplicitType, infer TExternalResult> ? ObjectSchemaBuilder<Omit<TProperties, keyof TProps>, TRequired, TExplicitType, Omit<TResult, keyof TProps>> : never;
220
+ omit<T>(schema: T): T extends ObjectSchemaBuilder<infer TProps, infer TRequired, infer TExplicitType> ? ObjectSchemaBuilder<Omit<TProperties, keyof TProps>, TRequired, TExplicitType> : never;
230
221
  /**
231
222
  * Adds all properties from `schema` to the current schema.
232
223
  * `TSchema & TAnotherSchema` is a good example of the similar concept
233
224
  * in the TS type system.
234
225
  * @param schema an object schema to take properties from
235
226
  */
236
- intersect<T extends ObjectSchemaBuilder<any, any, any, any, any>>(schema: T): T extends ObjectSchemaBuilder<infer TProps, infer TReq, infer TExplType, infer TRes, any> ? ObjectSchemaBuilder<Omit<TProperties, keyof TProps> & TProps, TRequired, TExplType, Omit<TResult, keyof TRes> & TRes> : never;
227
+ intersect<T extends ObjectSchemaBuilder<any, any, any>>(schema: T): T extends ObjectSchemaBuilder<infer TProps, infer TReq, infer TExplType> ? ObjectSchemaBuilder<Omit<TProperties, keyof TProps> & TProps, TRequired, TExplType> : never;
237
228
  /**
238
229
  * Marks all properties in the current schema as optional.
239
230
  * It is the same as call `.optional('propname')` where `propname` is the name
240
231
  * of every property in the schema.
241
232
  */
242
- partial(): ObjectSchemaBuilder<{
243
- [k in keyof TProperties]: ReturnType<TProperties[k]['optional']>;
244
- }, TRequired, TExplicitType, Partial<TResult>>;
233
+ partial(): ObjectSchemaBuilder<MakeChildrenOptional<TProperties>, TRequired, TExplicitType>;
245
234
  /**
246
235
  * Marks all properties from `properties` as optional in the schema.
247
236
  * @param properties list of property names (string) to make optional
248
237
  */
249
- partial<K extends keyof TProperties>(properties: K[]): ObjectSchemaBuilder<Omit<TProperties, K> & {
250
- [k in keyof TProperties as K extends k ? k : never]: ReturnType<TProperties[k]['optional']>;
251
- }, TRequired, TExplicitType, Omit<TResult, K> & {
252
- [k in keyof TResult as K extends k ? k : never]?: TResult[k];
253
- }>;
238
+ partial<K extends keyof TProperties>(properties: K[]): ObjectSchemaBuilder<Omit<TProperties, K> & Pick<MakeChildrenOptional<TProperties>, K>, TRequired, TExplicitType>;
254
239
  /**
255
240
  * Marks property `propName` as optional in the schema.
256
241
  * @param propName the name of the property (string).
257
242
  */
258
- partial<TProperty extends keyof TProperties>(propName: TProperty): ObjectSchemaBuilder<Omit<TProperties, TProperty> & {
259
- [k in TProperty]: ReturnType<TProperties[k]['optional']>;
260
- }, TRequired, TExplicitType, Omit<TResult, TProperty> & {
261
- [k in keyof TResult as TProperty extends k ? k : never]?: TResult[k];
262
- }>;
243
+ partial<TProperty extends keyof TProperties>(propName: TProperty): ObjectSchemaBuilder<Omit<TProperties, TProperty> & Pick<MakeChildrenOptional<TProperties>, TProperty>, TRequired, TExplicitType>;
263
244
  /**
264
245
  * Returns a new schema containing only properties listed in
265
246
  * `properties` array.
266
247
  * @param properties array of property names (strings)
267
248
  */
268
- pick<K extends keyof TProperties>(properties: K[]): ObjectSchemaBuilder<Pick<TProperties, K>, TRequired, undefined, {
269
- [k in keyof TResult as K extends k ? k : never]: TResult[k];
270
- }>;
249
+ pick<K extends keyof TProperties>(properties: K[]): ObjectSchemaBuilder<Pick<TProperties, K>, TRequired, undefined>;
271
250
  /**
272
251
  * Returns new schema based on the current schema. This new schema
273
252
  * will consists only from properties which names are taken from the
274
253
  * `schema` object schema.
275
254
  * @param schema schema to take property names list from
276
255
  */
277
- pick<K extends ObjectSchemaBuilder<any, any, any, any, any>>(schema: K): K extends ObjectSchemaBuilder<infer TProps, infer T1, infer T2, infer T3> ? ObjectSchemaBuilder<{
278
- [k in keyof TProps as k extends keyof TProperties ? k : never]: k extends keyof TProperties ? TProperties[k] : never;
279
- }, TRequired, undefined, {
280
- [k in keyof TProps as k extends keyof TProperties ? k : never]: k extends keyof TResult ? TResult[k] : never;
281
- }> : never;
256
+ pick<K extends ObjectSchemaBuilder<any, any, any>>(schema: K): K extends ObjectSchemaBuilder<infer TProps, infer T1, infer T2> ? ObjectSchemaBuilder<Omit<TProperties, keyof Omit<TProperties, keyof TProps>>, TRequired, undefined> : never;
282
257
  /**
283
258
  * Returns a new schema consisting of only one property
284
259
  * (taken from the `property` property name). If the property
285
260
  * does not exists in the current schema, an error will be thrown.
286
261
  * @param property the name of the property (string).
287
262
  */
288
- pick<K extends keyof TProperties>(property: K): ObjectSchemaBuilder<Pick<TProperties, K>, TRequired, undefined, K extends keyof TResult ? Pick<TResult, K> : TResult>;
263
+ pick<K extends keyof TProperties>(property: K): ObjectSchemaBuilder<Pick<TProperties, K>, TRequired, undefined>;
289
264
  /**
290
265
  * Modify schema for `propName` and return a new schema.
291
266
  * Could be useful if you want to leave all schema intact, but
@@ -295,65 +270,43 @@ export declare class ObjectSchemaBuilder<TProperties extends Record<string, Sche
295
270
  * you will receive an old schema for `propName`.
296
271
  * @returns
297
272
  */
298
- modifyPropSchema<K extends keyof TProperties, R extends SchemaBuilder<any, any>>(propName: K, callback: (builder: TProperties[K]) => R): ObjectSchemaBuilder<Omit<TProperties, K> & {
299
- [k in K]: R;
300
- }, TRequired, TExplicitType, R extends SchemaBuilder<infer S, infer TReq> ? Omit<TResult, K> & (TReq extends false ? {
301
- [k in K]?: InferType<R>;
302
- } : {
303
- [k in K]: InferType<R>;
304
- }) : never>;
273
+ modifyPropSchema<K extends keyof TProperties, R extends SchemaBuilder<any, any>>(propName: K, callback: (builder: TProperties[K]) => R): ObjectSchemaBuilder<ModifyPropSchema<TProperties, K, R>, TRequired, TExplicitType>;
305
274
  /**
306
275
  * An alias for `.partial(prop: string)`
307
276
  * @param prop name of the property
308
277
  */
309
- makePropOptional<K extends keyof TProperties, R = ReturnType<TProperties[K]['optional']>>(prop: K): ObjectSchemaBuilder<Omit<TProperties, K> & {
310
- [k in K]: R;
311
- }, TRequired, TExplicitType, R extends SchemaBuilder<infer S, infer TReq> ? Omit<TResult, K> & (TReq extends false ? {
312
- [k in K]?: InferType<R>;
313
- } : {
314
- [k in K]: InferType<R>;
315
- }) : never>;
278
+ makePropOptional<K extends keyof TProperties>(prop: K): ObjectSchemaBuilder<MakeChildOptional<TProperties, K>, TRequired, TExplicitType>;
316
279
  /**
317
280
  * Marks `prop` as required property.
318
281
  * If `prop` does not exists in the current schema,
319
282
  * an error will be thrown.
320
283
  * @param prop name of the property
321
284
  */
322
- makePropRequired<K extends keyof TProperties, R = ReturnType<TProperties[K]['required']>>(prop: K): ObjectSchemaBuilder<Omit<TProperties, K> & {
323
- [k in K]: R;
324
- }, TRequired, TExplicitType, R extends SchemaBuilder<infer S, infer TReq> ? Omit<TResult, K> & (TReq extends false ? {
325
- [k in K]?: InferType<R>;
326
- } : {
327
- [k in K]: InferType<R>;
328
- }) : never>;
285
+ makePropRequired<K extends keyof TProperties>(prop: K): ObjectSchemaBuilder<MakeChildRequired<TProperties, K>, TRequired, TExplicitType>;
329
286
  /**
330
287
  * `Partial<T>` would be a good example of the
331
288
  * same operation in the TS world.
332
289
  */
333
- makeAllPropsOptional(): ObjectSchemaBuilder<{
334
- [k in keyof TProperties]: ReturnType<TProperties[k]['optional']>;
335
- }, TRequired, TExplicitType, Partial<TResult>>;
290
+ makeAllPropsOptional(): ObjectSchemaBuilder<MakeChildrenOptional<TProperties>, TRequired, TExplicitType>;
336
291
  /**
337
292
  * `Required<T>` would be a good example of the
338
293
  * same operation in the TS world.
339
294
  */
340
- makeAllPropsRequired(): ObjectSchemaBuilder<{
341
- [k in keyof TProperties]: ReturnType<TProperties[k]['required']>;
342
- }, TRequired, TExplicitType, {
343
- [k in keyof TResult]: NonNullable<TResult[k]>;
344
- }>;
295
+ makeAllPropsRequired(): ObjectSchemaBuilder<MakeChildrenRequired<TProperties>, TRequired, TExplicitType>;
345
296
  }
346
297
  /**
347
298
  * Defines a schema for empty object `{}`
348
299
  */
349
- export declare function object(): ObjectSchemaBuilder<{}, true, undefined, {}>;
300
+ export declare function object(): ObjectSchemaBuilder<{}, true>;
350
301
  /**
351
302
  * Defines an object schema, properties definitions are takens from `props`.
352
303
  * @param props key/schema object map for schema's properties.
353
304
  */
354
- export declare function object<TProps extends Record<string, SchemaBuilder<any, any>>>(props: TProps): ObjectSchemaBuilder<{
355
- [k in keyof TProps]: TProps[k];
356
- }, true, undefined, {
357
- [k in keyof TProps]: InferType<TProps[k]>;
358
- }>;
305
+ export declare function object<TProps extends Record<string, SchemaBuilder<any, any>>>(props: TProps): ObjectSchemaBuilder<TProps, true>;
306
+ type RequiredProps<T extends Record<string, SchemaBuilder<any, any>>> = keyof {
307
+ [k in keyof T as T[k] extends SchemaBuilder<infer TRes, infer TReq> ? TReq extends true ? k : never : never]: T[k];
308
+ };
309
+ type NotRequiredProps<T extends Record<string, SchemaBuilder<any, any>>> = keyof {
310
+ [k in keyof T as T[k] extends SchemaBuilder<infer TRes, infer TReq> ? TReq extends true ? never : k : never]: T[k];
311
+ };
359
312
  export {};
@@ -308,6 +308,15 @@ export class ObjectSchemaBuilder extends SchemaBuilder {
308
308
  * @hidden
309
309
  * @deprecated this is for internal use, do not use if you are
310
310
  * not sure you need it.
311
+ *
312
+ * TODO: This is used to avoid `&` in resulting types. For example,
313
+ * when you have a schema like `object({prop1: string()})` and then use `addProp({prop2: string()})` method,
314
+ * the resulting type without `optimize` will be something like `{prop1: string} & {prop2: string}`. Which
315
+ * is not we would like to have. Instead we want to have `{prop1: string, prop2: string}`. This is what
316
+ * `optimize` method does. However it is not always possible to do this optimization without losing
317
+ * JSDoc comments, which is sucks. For example, I had to disable optimization for UnionSchemas, because
318
+ * comments were lost. Hopefully it will be fixed in the future by Typescript team or somebody will
319
+ * find a workaround/fix and create a pull request.
311
320
  */
312
321
  optimize() {
313
322
  return this.createFromProps({
@@ -6,7 +6,6 @@ export type ValidationError = {
6
6
  path: string;
7
7
  message: string;
8
8
  };
9
- export type MakeRequired<T> = NonNullable<T>;
10
9
  export type MakeOptional<T> = {
11
10
  prop?: T;
12
11
  }['prop'];
@@ -1,6 +1,9 @@
1
1
  import { SchemaBuilder, ValidationResult, ValidationContext, InferType } from './SchemaBuilder.js';
2
2
  type UnionSchemaBuilderCreateProps<T extends readonly SchemaBuilder<any, any>[], R extends boolean = true> = Partial<ReturnType<UnionSchemaBuilder<T, R>['introspect']>>;
3
- type SchemaArrayToUnion<TArr extends readonly any[]> = TArr['length'] extends 1 ? InferType<TArr[0]> : TArr extends readonly [infer TFirst, ...infer TRest] ? InferType<TFirst> | SchemaArrayToUnion<[...TRest]> : never;
3
+ type SchemaArrayToUnion<TArr extends readonly SchemaBuilder<any, any>[]> = TArr['length'] extends 1 ? InferType<TArr[0]> : TArr extends readonly [
4
+ infer TFirst extends SchemaBuilder<any, any>,
5
+ ...infer TRest extends SchemaBuilder<any, any>[]
6
+ ] ? InferType<TFirst> | SchemaArrayToUnion<[...TRest]> : never;
4
7
  type TakeBeforeIndex<TArr extends readonly SchemaBuilder<any, any>[], TIndex extends number> = TArr extends [
5
8
  ...infer TRest extends SchemaBuilder<any, any>[],
6
9
  infer TLast extends SchemaBuilder<any, any>
@@ -60,9 +63,9 @@ type TakeExceptIndex<TArr extends readonly SchemaBuilder<any, any>[], TIndex ext
60
63
  *
61
64
  * @see {@link union}
62
65
  */
63
- export declare class UnionSchemaBuilder<TOptions extends readonly SchemaBuilder<any, any>[], TRequired extends boolean = true, TExplicitType = undefined, TResult = TExplicitType extends undefined ? SchemaArrayToUnion<TOptions> : TExplicitType> extends SchemaBuilder<TResult, TRequired> {
66
+ export declare class UnionSchemaBuilder<TOptions extends readonly SchemaBuilder<any, any>[], TRequired extends boolean = true, TExplicitType = undefined> extends SchemaBuilder<TExplicitType extends undefined ? SchemaArrayToUnion<TOptions> : TExplicitType, TRequired> {
64
67
  #private;
65
- static create(props: UnionSchemaBuilderCreateProps<any>): UnionSchemaBuilder<any, true, undefined, any>;
68
+ static create(props: UnionSchemaBuilderCreateProps<any>): UnionSchemaBuilder<any, true, undefined>;
66
69
  private constructor();
67
70
  introspect(): {
68
71
  /**
@@ -71,8 +74,8 @@ export declare class UnionSchemaBuilder<TOptions extends readonly SchemaBuilder<
71
74
  options: TOptions;
72
75
  type: string;
73
76
  isRequired: boolean;
74
- preprocessors: readonly import("./SchemaBuilder.js").Preprocessor<TResult>[];
75
- validators: readonly import("./SchemaBuilder.js").Validator<TResult>[];
77
+ preprocessors: readonly import("./SchemaBuilder.js").Preprocessor<TExplicitType extends undefined ? SchemaArrayToUnion<TOptions> : TExplicitType>[];
78
+ validators: readonly import("./SchemaBuilder.js").Validator<TExplicitType extends undefined ? SchemaArrayToUnion<TOptions> : TExplicitType>[];
76
79
  };
77
80
  /**
78
81
  * @hidden
@@ -86,7 +89,7 @@ export declare class UnionSchemaBuilder<TOptions extends readonly SchemaBuilder<
86
89
  * Performs validion of the union schema over `object`.
87
90
  * @param context Optional `ValidationContext` settings.
88
91
  */
89
- validate(object: TResult, context?: ValidationContext): Promise<ValidationResult<TResult>>;
92
+ validate(object: TExplicitType extends undefined ? SchemaArrayToUnion<TOptions> : TExplicitType, context?: ValidationContext): Promise<ValidationResult<TExplicitType extends undefined ? SchemaArrayToUnion<TOptions> : TExplicitType>>;
90
93
  protected createFromProps<T extends readonly SchemaBuilder<any, any>[], TReq extends boolean>(props: UnionSchemaBuilderCreateProps<T, TReq>): this;
91
94
  /**
92
95
  * @hidden
@@ -126,5 +129,5 @@ export declare class UnionSchemaBuilder<TOptions extends readonly SchemaBuilder<
126
129
  * Creates a union schema.
127
130
  * @param schema required and will be considered as a first option for the union shchema.
128
131
  */
129
- export declare const union: <T extends SchemaBuilder<any, any>>(schema: T) => UnionSchemaBuilder<[T], true, undefined, InferType<T>>;
132
+ export declare const union: <T extends SchemaBuilder<any, any>>(schema: T) => UnionSchemaBuilder<[T], true, undefined>;
130
133
  export {};
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export { NumberSchemaBuilder } from './builders/NumberSchemaBuilder.js';
8
8
  export { StringSchemaBuilder } from './builders/StringSchemaBuilder.js';
9
9
  export { UnionSchemaBuilder } from './builders/UnionSchemaBuilder.js';
10
10
  export { SchemaBuilder } from './builders/SchemaBuilder.js';
11
- export { InferType, MakeOptional, MakeRequired, ValidationError, ValidationResult } from './builders/SchemaBuilder.js';
11
+ export { InferType, MakeOptional, ValidationError, ValidationResult } from './builders/SchemaBuilder.js';
12
12
  export { any } from './builders/AnySchemaBuilder.js';
13
13
  export { array } from './builders/ArraySchemaBuilder.js';
14
14
  export { boolean } from './builders/BooleanSchemaBuilder.js';
package/package.json CHANGED
@@ -6,9 +6,9 @@
6
6
  },
7
7
  "description": "Schema Definition And Validation library, that allows to define and validate objects of any complexity",
8
8
  "files": [
9
- "dist/**/*"
9
+ "dist"
10
10
  ],
11
- "homepage": "https://docs.cleverbrush.com/v1.0.0/modules/Schema_Definition_And_Validation.html",
11
+ "homepage": "https://docs.cleverbrush.com/v1.1.1/modules/Schema_Definition_And_Validation.html",
12
12
  "keywords": [
13
13
  "object schema validator",
14
14
  "schema",
@@ -35,8 +35,8 @@
35
35
  "displayName": "Schema Definition And Validation",
36
36
  "tsconfig": "./tsconfig.json"
37
37
  },
38
- "version": "1.0.0",
38
+ "version": "1.1.1",
39
39
  "devDependencies": {
40
- "@cleverbrush/deep": "1.0.0"
40
+ "@cleverbrush/deep": "1.1.1"
41
41
  }
42
42
  }