Skip to content

Commit

Permalink
fix: #61 issue (#62)
Browse files Browse the repository at this point in the history
* fix: #61 issue

* fix: add jsdoc and test for parsing object
  • Loading branch information
vitalics authored Sep 3, 2024
1 parent 0aeb8dc commit 37a7b1d
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .changeset/fair-dolls-lick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ajv-ts": patch
---

fix # 61
10 changes: 10 additions & 0 deletions UPCOMING.md
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
# x.x.x

## 💥 Breaking Changes

## ✅ New Features

## 🐛 Bug Fixes

- [#61](https://github.com/vitalics/ajv-ts/issues/61)

## 🏡 Chore/Infra
19 changes: 8 additions & 11 deletions src/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,15 +228,7 @@ export class SchemaBuilder<
* schemaDef.schema // { type: ['string', 'null'], nullable: true }
*/
nullable(): SchemaBuilder<Input, Schema, Output | null> {
this.isNullable = true;
(this.schema as any).nullable = true;
const type = (this.schema as any).type;
if (Array.isArray(type)) {
(this.schema as any).type = [...new Set([...type, "null"])];
} else {
(this.schema as any).type = [...new Set([type, "null"])];
}
return this as never;
return or(this, nil()) as never
}

private preFns: Function[] = [];
Expand Down Expand Up @@ -1306,8 +1298,12 @@ class ObjectSchemaBuilder<
/**
* Disallow additional properties for object schema `additionalProperties=false`
*
* If you would like to define additional properties type - use `additionalProeprties`
* If you would like to define additional properties type - use `additionalProperties`
* @see {@link ObjectSchemaBuilder.additionalProperties additionalProperties}
*
* If you would like to mark properties required - use `required` or `requiredFor`
* @see {@link ObjectSchemaBuilder.required required}
* @see {@link ObjectSchemaBuilder.requiredFor requiredFor}
*/
strict() {
this.schema.additionalProperties = false;
Expand All @@ -1334,7 +1330,8 @@ class ObjectSchemaBuilder<
/**
* Make **ALL** properties in your object required.
*
* If you need to make 1 property required - use {@link ObjectSchemaBuilder.requiredFor}
* If you need to make few required properties (1 or more, not everything fields) - use `requiredFor`
* @see {@link ObjectSchemaBuilder.requiredFor requiredFor}
*/
required(): ObjectSchemaBuilder<Definition, Required<T>> {
const allProperties = Object.keys(this.schema.properties!);
Expand Down
18 changes: 18 additions & 0 deletions tests/enum.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,21 @@ test("from const", () => {
expect(GreekEnum.enum.Alpha).toEqual("a");
});

test('#61 nullable enum', () => {
const sex = s.enum(['male', 'female']);
const nullableSex = s.enum(['male', 'female']).nullable();

const optionalNullableObj = s.object({
sex: s.enum(['male', 'female']).nullable().optional(),
});

expect(sex.parse('male')).toBe('male');
expect(sex.parse('female')).toBe('female');
expect(sex.validate(null)).toBe(false);
expect(sex.validate(undefined)).toBe(false);

expect(nullableSex.parse('male'),).toBe('male');
expect(nullableSex.parse('female'),).toBe('female');
expect(nullableSex.validate(null)).toBe(true);
expect(nullableSex.validate(undefined)).toBe(false);
})
28 changes: 28 additions & 0 deletions tests/object.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,3 +446,31 @@ test('#57 merge() should not contains undefined after merge', () => {
wheels: 4
})
})

test('#61 optional nullable object schema should parsed successfully', () => {
const optionalNullableObj = s.object({
sex: s.enum(['male', 'female']).nullable().optional(),
});

expect(optionalNullableObj.parse({})).toStrictEqual({});
expect(optionalNullableObj.parse({ sex: 'male' })).toStrictEqual({ sex: 'male' });
expect(optionalNullableObj.parse({ sex: null })).toStrictEqual({ sex: null });
})

test('#61 should parse big schema successfully', () => {
const schema2 = s.object({
name: s.string().minLength(2).maxLength(20),
age: s.number().integer().min(0).max(100),

// default optional - string | null | undefined
email: s.string().format('email').nullable().optional().default(null),

//optional - string | null | undefined
phone: s.string().nullable().optional(),

// required - string | null
surname: s.string().nullable(),
}).strict();

expect(schema2.parse({ name: 'Alex', age: 10, })).toStrictEqual({ name: 'Alex', age: 10, email: null });
})
20 changes: 20 additions & 0 deletions tests/union.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { test, expect } from 'vitest'

import s from '../src'

test('#61 enum with constant values should work', () => {

const externalJSONSchema = {
anyOf: [{ const: 'lt' }, { const: 'gt' }],
}
const schema1 = s.fromJSON(externalJSONSchema);

const schema2 = s.union(s.literal('lt'), s.literal('gt'));

expect(schema2.schema).toStrictEqual(externalJSONSchema);

expect(schema1.parse('gt')).toBe('gt'); // gt
expect(schema1.parse('lt')).toBe('lt'); // lt

expect(schema2.parse('gt')).toBe('gt');
})

0 comments on commit 37a7b1d

Please sign in to comment.