Skip to content

Commit fd3862e

Browse files
committed
Add support for nullables
1 parent caced07 commit fd3862e

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

src/2020.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export type NullSchema = BaseSchema & {
163163

164164
export const $schema = "https://json-schema.org/draft/2020-12/schema";
165165

166-
class SchemaBuilder<S extends Schema> {
166+
export class SchemaBuilder<S extends Schema> {
167167
schema: S;
168168

169169
constructor(s: S) {
@@ -445,6 +445,27 @@ function boolean(options?: Omit<BooleanSchema, "type">): SchemaBuilder<BooleanSc
445445
});
446446
}
447447

448+
function nullable(schema: SchemaBuilder<Schema>): SchemaBuilder<Schema> {
449+
const nullableSchema = schema.toSchema();
450+
451+
if (
452+
typeof nullableSchema === "boolean" ||
453+
nullableSchema.type === "null" ||
454+
typeof nullableSchema.type === "undefined"
455+
) {
456+
return schema;
457+
}
458+
459+
const type = Array.isArray(nullableSchema.type)
460+
? nullableSchema.type.concat(<const>"null")
461+
: [nullableSchema.type, <const>"null"];
462+
463+
return new SchemaBuilder({
464+
...nullableSchema,
465+
type,
466+
});
467+
}
468+
448469
function anyOf(...schemas: SchemaBuilder<Schema>[]): SchemaBuilder<Schema> {
449470
return new SchemaBuilder({
450471
anyOf: schemas.map((s) => s.toSchema()),
@@ -517,6 +538,14 @@ function enumerator(...values: any[]): SchemaBuilder<Schema> {
517538
});
518539
}
519540

541+
function $false(): SchemaBuilder<Schema> {
542+
return new SchemaBuilder(false);
543+
}
544+
545+
function $true(): SchemaBuilder<Schema> {
546+
return new SchemaBuilder(true);
547+
}
548+
520549
export const s = {
521550
object,
522551
properties,
@@ -529,6 +558,7 @@ export const s = {
529558
number,
530559
nil,
531560
boolean,
561+
nullable,
532562
anyOf,
533563
allOf,
534564
oneOf,
@@ -539,4 +569,6 @@ export const s = {
539569
ref,
540570
constant,
541571
enumerator,
572+
$false,
573+
$true,
542574
};

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export type {
1010
AnySchema,
1111
StringFormat,
1212
PropertiesSchema,
13+
SchemaBuilder,
1314
} from "./2020";
1415

1516
export { $schema, s } from "./2020";

tests/2020.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,31 @@ describe("const and enums", () => {
557557
});
558558
});
559559

560+
describe("nullables", () => {
561+
test("Should allow a type to be null", () => {
562+
expect(s.nullable(s.string()).toSchemaDocument()).toStrictEqual({
563+
$schema,
564+
type: ["string", "null"],
565+
});
566+
567+
expect(s.nullable(s.string({ format: "email" })).toSchemaDocument()).toStrictEqual({
568+
$schema,
569+
type: ["string", "null"],
570+
format: "email",
571+
});
572+
573+
expect(
574+
s.nullable(s.object({ properties: [s.property("foo", s.string())] })).toSchemaDocument(),
575+
).toStrictEqual({
576+
$schema,
577+
type: ["object", "null"],
578+
properties: {
579+
foo: { type: "string" },
580+
},
581+
});
582+
});
583+
});
584+
560585
describe("types", () => {
561586
test("Types to create object schemas", () => {
562587
const foo: ObjectSchema = {

0 commit comments

Comments
 (0)