Skip to content

Commit 781725f

Browse files
author
andy.patterson
committed
feat: add ability to perform additional validations
1 parent 3adf0b1 commit 781725f

File tree

3 files changed

+68
-2
lines changed

3 files changed

+68
-2
lines changed

src/index.ts

+47-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,30 @@
1-
import { Schema, SchemaMetaData } from 'type-level-schema/schema';
2-
import { objectKeys, Nominal, AnyFunc, AllRequired, Optional, Unknown, PlainObject } from 'simplytyped';
1+
import { objectKeys, Nominal, AnyFunc, AllRequired, Optional, Unknown, PlainObject, Omit } from 'simplytyped';
32
import * as Ajv from 'ajv';
43

4+
// Schema definitions
5+
import { Schema, SchemaMetaData } from 'type-level-schema/schema';
6+
import { StringSchema } from 'type-level-schema/defs/string';
7+
import { NumberSchema } from 'type-level-schema/defs/number';
8+
import { BooleanSchema } from 'type-level-schema/defs/boolean';
9+
import { ArraySchema } from 'type-level-schema/defs/array';
10+
import { ObjectSchema } from 'type-level-schema/defs/object';
11+
12+
/**
13+
* no-doc - Gets the full schema definition for a given type.
14+
*/
15+
export type TypeToSchema<T> =
16+
T extends string ? StringSchema :
17+
T extends number ? NumberSchema :
18+
T extends boolean ? BooleanSchema :
19+
T extends any[] ? ArraySchema :
20+
T extends object ? ObjectSchema :
21+
never;
22+
23+
/**
24+
* no-doc - Gets the optional parts of the schema definition for a given type.
25+
*/
26+
export type TypeToSchemaOptions<T> = Omit<TypeToSchema<T>, 'type'>;
27+
528
/**
629
* no-doc - Generates an object type from `[string, Validator]` pairs
730
* @param O a Validator record
@@ -182,6 +205,28 @@ export class Validator<T> {
182205
return this;
183206
}
184207

208+
/**
209+
* Add additional validations to the generated schema.
210+
* While most of these validations are not representable at compile time
211+
* with typescript (`minLength` of a `string` for instance), it can be helpful
212+
* to have the additional validations when validating runtime types.
213+
* @param opts JSON schema specific options (for instance: `{ maxLength: 2, minLength: 0 }`)
214+
*
215+
* @example
216+
* ```typescript
217+
* const validator = v.string().withOptions({ minLength: 1 });
218+
* validator.isValid(''); // false
219+
* validator.isValid('hi'); // true
220+
* ```
221+
*/
222+
withOptions(opts: TypeToSchemaOptions<T>): this {
223+
this.schema = {
224+
...this.schema,
225+
...opts as any,
226+
};
227+
return this;
228+
}
229+
185230
/**
186231
* Creates a new validator that is true whenever the data matches `this` _or_ `v`.
187232
* @param other Another validator instance whose type will form a union with `this` encapsulated type.

tests/unit/array.test.ts

+11
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,14 @@ test('Can validate a deep array', () => {
3030
fail();
3131
}
3232
});
33+
34+
test('Can add JSON Schema options', () => {
35+
const x: any = [ 'yellow!' ];
36+
37+
const validator = v.array(v.any())
38+
.withOptions({ minItems: 2 });
39+
40+
// expect to fail because we have fewer than 2 items
41+
if (validator.isValid(x)) fail();
42+
else pass();
43+
});

tests/unit/string.test.ts

+10
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,13 @@ test('String is not in enum', () => {
3535
if (validator.isValid(x)) fail();
3636
else pass();
3737
});
38+
39+
test('Can add JSON Schema options', () => {
40+
const x: any = '';
41+
42+
const validator = v.string()
43+
.withOptions({ minLength: 1 });
44+
45+
if (validator.isValid(x)) fail();
46+
else pass();
47+
});

0 commit comments

Comments
 (0)