Skip to content

Commit

Permalink
#176 added support for bigint
Browse files Browse the repository at this point in the history
  • Loading branch information
AGalabov committed Oct 17, 2023
1 parent 5fa23f4 commit 0cb3c0b
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 15 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ The list of all supported types as of now is:

- `ZodAny`
- `ZodArray`
- `ZodBigInt`
- `ZodBoolean`
- `ZodDate`
- `ZodDefault`
Expand Down
92 changes: 92 additions & 0 deletions spec/types/bigint.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { z } from 'zod';
import { expectSchema } from '../lib/helpers';

describe('bigint', () => {
it('generates OpenAPI schema for a simple bigint type', () => {
expectSchema([z.bigint().openapi('SimpleBigInt')], {
SimpleBigInt: { type: 'integer', format: 'int64' },
});
});

it('supports minimum in open api 3.0.0', () => {
expectSchema([z.bigint().gte(BigInt(0)).openapi('SimpleBigInteger')], {
SimpleBigInteger: { type: 'integer', format: 'int64', minimum: 0 },
});
});

it('supports exclusive minimum in open api 3.0.0', () => {
expectSchema([z.bigint().gt(BigInt(0)).openapi('SimpleBigInteger')], {
SimpleBigInteger: {
type: 'integer',
format: 'int64',
minimum: 0,
exclusiveMinimum: true,
},
});
});

it('supports maximum in open api 3.0.0', () => {
expectSchema([z.bigint().lte(BigInt(0)).openapi('SimpleBigInteger')], {
SimpleBigInteger: { type: 'integer', format: 'int64', maximum: 0 },
});
});

it('supports exclusive maximum in open api 3.0.0', () => {
expectSchema([z.bigint().lt(BigInt(0)).openapi('SimpleBigInteger')], {
SimpleBigInteger: {
type: 'integer',
format: 'int64',
maximum: 0,
exclusiveMaximum: true,
},
});
});

it('supports minimum in open api 3.1.0', () => {
expectSchema(
[z.bigint().gte(BigInt(0)).openapi('SimpleBigInteger')],
{
SimpleBigInteger: { type: 'integer', format: 'int64', minimum: 0 },
},
'3.1.0'
);
});

it('supports exclusive minimum in open api 3.1.0', () => {
expectSchema(
[z.bigint().gt(BigInt(0)).openapi('SimpleBigInteger')],
{
SimpleBigInteger: {
type: 'integer',
format: 'int64',
exclusiveMinimum: 0,
} as never,
},
'3.1.0'
);
});

it('supports maximum in open api 3.1.0', () => {
expectSchema(
[z.bigint().lte(BigInt(0)).openapi('SimpleBigInteger')],
{
SimpleBigInteger: { type: 'integer', format: 'int64', maximum: 0 },
},
'3.1.0'
);
});

it('supports exclusive maximum in open api 3.1.0', () => {
expectSchema(
[z.bigint().lt(BigInt(0)).openapi('SimpleBigInteger')],
{
SimpleBigInteger: {
type: 'integer',
format: 'int64',
exclusiveMaximum: 0,
} as never,
},
'3.1.0'
);
});
});
1 change: 1 addition & 0 deletions src/lib/zod-is-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { z } from 'zod';
type ZodTypes = {
ZodAny: z.ZodAny;
ZodArray: z.ZodArray<any>;
ZodBigInt: z.ZodBigInt;
ZodBoolean: z.ZodBoolean;
ZodBranded: z.ZodBranded<any, any>;
ZodDefault: z.ZodDefault<any>;
Expand Down
15 changes: 12 additions & 3 deletions src/openapi-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ type HeadersObject = HeadersObject30 & HeadersObject31;

import type {
AnyZodObject,
ZodNumberDef,
ZodObject,
ZodRawShape,
ZodString,
Expand Down Expand Up @@ -80,6 +79,7 @@ import {
ZodRequestBody,
} from './openapi-registry';
import { ZodOpenApiFullMetadata, ZodOpenAPIMetadata } from './zod-extensions';
import { ZodNumericCheck } from './types';

// See https://github.com/colinhacks/zod/blob/9eb7eb136f3e702e86f030e6984ef20d4d8521b6/src/types.ts#L1370
type UnknownKeysParam = 'passthrough' | 'strict' | 'strip';
Expand All @@ -104,7 +104,7 @@ export interface OpenApiVersionSpecifics {
isNullable: boolean
): Pick<SchemaObject, 'type' | 'nullable'>;

getNumberChecks(checks: ZodNumberDef['checks']): any;
getNumberChecks(checks: ZodNumericCheck[]): any;
}

export class OpenAPIGenerator {
Expand Down Expand Up @@ -760,7 +760,7 @@ export class OpenAPIGenerator {
}

private getNumberChecks(
checks: ZodNumberDef['checks']
checks: ZodNumericCheck[]
): Pick<
SchemaObject,
'minimum' | 'exclusiveMinimum' | 'maximum' | 'exclusiveMaximum'
Expand Down Expand Up @@ -828,6 +828,15 @@ export class OpenAPIGenerator {
};
}

if (isZodType(zodSchema, 'ZodBigInt')) {
return {
...this.mapNullableType('integer', isNullable),
...this.getNumberChecks(zodSchema._def.checks),
format: 'int64',
default: defaultValue,
};
}

if (isZodType(zodSchema, 'ZodBoolean')) {
return {
...this.mapNullableType('boolean', isNullable),
Expand Down
3 changes: 3 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { ZodBigIntCheck, ZodNumberCheck } from 'zod';

export type ZodNumericCheck = ZodNumberCheck | ZodBigIntCheck;
12 changes: 6 additions & 6 deletions src/v3.0/specifics.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ReferenceObject, SchemaObject } from 'openapi3-ts/oas30';
import { ZodNumberDef } from 'zod';
import { OpenApiVersionSpecifics } from '../openapi-generator';
import { ZodNumericCheck } from '../types';

export class OpenApiGeneratorV30Specifics implements OpenApiVersionSpecifics {
get nullType() {
Expand Down Expand Up @@ -28,7 +28,7 @@ export class OpenApiGeneratorV30Specifics implements OpenApiVersionSpecifics {
}

getNumberChecks(
checks: ZodNumberDef['checks']
checks: ZodNumericCheck[]
): Pick<
SchemaObject,
'minimum' | 'exclusiveMinimum' | 'maximum' | 'exclusiveMaximum'
Expand All @@ -39,13 +39,13 @@ export class OpenApiGeneratorV30Specifics implements OpenApiVersionSpecifics {
switch (check.kind) {
case 'min':
return check.inclusive
? { minimum: check.value }
: { minimum: check.value, exclusiveMinimum: true };
? { minimum: Number(check.value) }
: { minimum: Number(check.value), exclusiveMinimum: true };

case 'max':
return check.inclusive
? { maximum: check.value }
: { maximum: check.value, exclusiveMaximum: true };
? { maximum: Number(check.value) }
: { maximum: Number(check.value), exclusiveMaximum: true };

default:
return {};
Expand Down
12 changes: 6 additions & 6 deletions src/v3.1/specifics.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ReferenceObject, SchemaObject } from 'openapi3-ts/oas31';

import type { ZodNumberDef } from 'zod';
import { OpenApiVersionSpecifics } from '../openapi-generator';
import { ZodNumericCheck } from '../types';

export class OpenApiGeneratorV31Specifics implements OpenApiVersionSpecifics {
get nullType() {
Expand Down Expand Up @@ -40,7 +40,7 @@ export class OpenApiGeneratorV31Specifics implements OpenApiVersionSpecifics {
}

getNumberChecks(
checks: ZodNumberDef['checks']
checks: ZodNumericCheck[]
): Pick<
SchemaObject,
'minimum' | 'exclusiveMinimum' | 'maximum' | 'exclusiveMaximum'
Expand All @@ -51,13 +51,13 @@ export class OpenApiGeneratorV31Specifics implements OpenApiVersionSpecifics {
switch (check.kind) {
case 'min':
return check.inclusive
? { minimum: check.value }
: { exclusiveMinimum: check.value };
? { minimum: Number(check.value) }
: { exclusiveMinimum: Number(check.value) };

case 'max':
return check.inclusive
? { maximum: check.value }
: { exclusiveMaximum: check.value };
? { maximum: Number(check.value) }
: { exclusiveMaximum: Number(check.value) };

default:
return {};
Expand Down

0 comments on commit 0cb3c0b

Please sign in to comment.