Skip to content

Commit

Permalink
🔀 Merge pull request #164 from NanezX/fix-circular-dependencies
Browse files Browse the repository at this point in the history
Fix circular dependencies
  • Loading branch information
StefanTerdell authored Feb 20, 2025
2 parents d80922a + bb49396 commit 99cc467
Show file tree
Hide file tree
Showing 22 changed files with 226 additions and 180 deletions.
2 changes: 1 addition & 1 deletion src/Options.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ZodSchema, ZodTypeDef } from "zod";
import { Refs, Seen } from "./Refs";
import { JsonSchema7Type } from "./parseDef";
import { JsonSchema7Type } from "./parseTypes";

export type Targets = "jsonSchema7" | "jsonSchema2019-09" | "openApi3" | "openAi";

Expand Down
2 changes: 1 addition & 1 deletion src/Refs.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ZodTypeDef } from "zod";
import { getDefaultOptions, Options, Targets } from "./Options.js";
import { JsonSchema7Type } from "./parseDef.js";
import { JsonSchema7Type } from "./parseTypes.js";

export type Refs = {
seen: Map<ZodTypeDef, Seen>;
Expand Down
2 changes: 1 addition & 1 deletion src/errorMessages.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { JsonSchema7TypeUnion } from "./parseDef.js";
import { JsonSchema7TypeUnion } from "./parseTypes.js";
import { Refs } from "./Refs.js";

export type ErrorMessages<
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export * from "./Options.js";
export * from "./Refs.js";
export * from "./errorMessages.js";
export * from "./parseDef.js";
export * from "./parseTypes.js";
export * from "./parsers/any.js";
export * from "./parsers/array.js";
export * from "./parsers/bigint.js";
Expand Down Expand Up @@ -32,6 +33,7 @@ export * from "./parsers/tuple.js";
export * from "./parsers/undefined.js";
export * from "./parsers/union.js";
export * from "./parsers/unknown.js";
export * from "./selectParser.js";
export * from "./zodToJsonSchema.js";
import { zodToJsonSchema } from "./zodToJsonSchema.js";
export default zodToJsonSchema;
173 changes: 11 additions & 162 deletions src/parseDef.ts
Original file line number Diff line number Diff line change
@@ -1,84 +1,8 @@
import { ZodFirstPartyTypeKind, ZodTypeDef } from "zod";
import { JsonSchema7AnyType, parseAnyDef } from "./parsers/any.js";
import { JsonSchema7ArrayType, parseArrayDef } from "./parsers/array.js";
import { JsonSchema7BigintType, parseBigintDef } from "./parsers/bigint.js";
import { JsonSchema7BooleanType, parseBooleanDef } from "./parsers/boolean.js";
import { parseBrandedDef } from "./parsers/branded.js";
import { parseCatchDef } from "./parsers/catch.js";
import { JsonSchema7DateType, parseDateDef } from "./parsers/date.js";
import { parseDefaultDef } from "./parsers/default.js";
import { parseEffectsDef } from "./parsers/effects.js";
import { JsonSchema7EnumType, parseEnumDef } from "./parsers/enum.js";
import {
JsonSchema7AllOfType,
parseIntersectionDef,
} from "./parsers/intersection.js";
import { JsonSchema7LiteralType, parseLiteralDef } from "./parsers/literal.js";
import { JsonSchema7MapType, parseMapDef } from "./parsers/map.js";
import {
JsonSchema7NativeEnumType,
parseNativeEnumDef,
} from "./parsers/nativeEnum.js";
import { JsonSchema7NeverType, parseNeverDef } from "./parsers/never.js";
import { JsonSchema7NullType, parseNullDef } from "./parsers/null.js";
import {
JsonSchema7NullableType,
parseNullableDef,
} from "./parsers/nullable.js";
import { JsonSchema7NumberType, parseNumberDef } from "./parsers/number.js";
import { JsonSchema7ObjectType, parseObjectDef } from "./parsers/object.js";
import { parseOptionalDef } from "./parsers/optional.js";
import { parsePipelineDef } from "./parsers/pipeline.js";
import { parsePromiseDef } from "./parsers/promise.js";
import { JsonSchema7RecordType, parseRecordDef } from "./parsers/record.js";
import { JsonSchema7SetType, parseSetDef } from "./parsers/set.js";
import { JsonSchema7StringType, parseStringDef } from "./parsers/string.js";
import { JsonSchema7TupleType, parseTupleDef } from "./parsers/tuple.js";
import {
JsonSchema7UndefinedType,
parseUndefinedDef,
} from "./parsers/undefined.js";
import { JsonSchema7UnionType, parseUnionDef } from "./parsers/union.js";
import { JsonSchema7UnknownType, parseUnknownDef } from "./parsers/unknown.js";
import { ZodTypeDef } from "zod";
import { Refs, Seen } from "./Refs.js";
import { parseReadonlyDef } from "./parsers/readonly.js";
import { ignoreOverride } from "./Options.js";

type JsonSchema7RefType = { $ref: string };
type JsonSchema7Meta = {
title?: string;
default?: any;
description?: string;
markdownDescription?: string;
};

export type JsonSchema7TypeUnion =
| JsonSchema7StringType
| JsonSchema7ArrayType
| JsonSchema7NumberType
| JsonSchema7BigintType
| JsonSchema7BooleanType
| JsonSchema7DateType
| JsonSchema7EnumType
| JsonSchema7LiteralType
| JsonSchema7NativeEnumType
| JsonSchema7NullType
| JsonSchema7NumberType
| JsonSchema7ObjectType
| JsonSchema7RecordType
| JsonSchema7TupleType
| JsonSchema7UnionType
| JsonSchema7UndefinedType
| JsonSchema7RefType
| JsonSchema7NeverType
| JsonSchema7MapType
| JsonSchema7AnyType
| JsonSchema7NullableType
| JsonSchema7AllOfType
| JsonSchema7UnknownType
| JsonSchema7SetType;

export type JsonSchema7Type = JsonSchema7TypeUnion & JsonSchema7Meta;
import { JsonSchema7Type } from "./parseTypes.js";
import { selectParser } from "./selectParser.js";

export function parseDef(
def: ZodTypeDef,
Expand Down Expand Up @@ -112,7 +36,12 @@ export function parseDef(

refs.seen.set(def, newItem);

const jsonSchema = selectParser(def, (def as any).typeName, refs);
let jsonSchema = selectParser(def, (def as any).typeName, refs);

// If the return was strictly null, then it's a call to parseDef (recursive)
if (jsonSchema === null) {
jsonSchema = parseDef((def as any).getter()._def, refs)
}

if (jsonSchema) {
addMeta(def, refs, jsonSchema);
Expand All @@ -128,8 +57,8 @@ const get$ref = (
refs: Refs,
):
| {
$ref: string;
}
$ref: string;
}
| {}
| undefined => {
switch (refs.$refStrategy) {
Expand Down Expand Up @@ -165,86 +94,6 @@ const getRelativePath = (pathA: string[], pathB: string[]) => {
return [(pathA.length - i).toString(), ...pathB.slice(i)].join("/");
};

const selectParser = (
def: any,
typeName: ZodFirstPartyTypeKind,
refs: Refs,
): JsonSchema7Type | undefined => {
switch (typeName) {
case ZodFirstPartyTypeKind.ZodString:
return parseStringDef(def, refs);
case ZodFirstPartyTypeKind.ZodNumber:
return parseNumberDef(def, refs);
case ZodFirstPartyTypeKind.ZodObject:
return parseObjectDef(def, refs);
case ZodFirstPartyTypeKind.ZodBigInt:
return parseBigintDef(def, refs);
case ZodFirstPartyTypeKind.ZodBoolean:
return parseBooleanDef();
case ZodFirstPartyTypeKind.ZodDate:
return parseDateDef(def, refs);
case ZodFirstPartyTypeKind.ZodUndefined:
return parseUndefinedDef();
case ZodFirstPartyTypeKind.ZodNull:
return parseNullDef(refs);
case ZodFirstPartyTypeKind.ZodArray:
return parseArrayDef(def, refs);
case ZodFirstPartyTypeKind.ZodUnion:
case ZodFirstPartyTypeKind.ZodDiscriminatedUnion:
return parseUnionDef(def, refs);
case ZodFirstPartyTypeKind.ZodIntersection:
return parseIntersectionDef(def, refs);
case ZodFirstPartyTypeKind.ZodTuple:
return parseTupleDef(def, refs);
case ZodFirstPartyTypeKind.ZodRecord:
return parseRecordDef(def, refs);
case ZodFirstPartyTypeKind.ZodLiteral:
return parseLiteralDef(def, refs);
case ZodFirstPartyTypeKind.ZodEnum:
return parseEnumDef(def);
case ZodFirstPartyTypeKind.ZodNativeEnum:
return parseNativeEnumDef(def);
case ZodFirstPartyTypeKind.ZodNullable:
return parseNullableDef(def, refs);
case ZodFirstPartyTypeKind.ZodOptional:
return parseOptionalDef(def, refs);
case ZodFirstPartyTypeKind.ZodMap:
return parseMapDef(def, refs);
case ZodFirstPartyTypeKind.ZodSet:
return parseSetDef(def, refs);
case ZodFirstPartyTypeKind.ZodLazy:
return parseDef(def.getter()._def, refs);
case ZodFirstPartyTypeKind.ZodPromise:
return parsePromiseDef(def, refs);
case ZodFirstPartyTypeKind.ZodNaN:
case ZodFirstPartyTypeKind.ZodNever:
return parseNeverDef();
case ZodFirstPartyTypeKind.ZodEffects:
return parseEffectsDef(def, refs);
case ZodFirstPartyTypeKind.ZodAny:
return parseAnyDef();
case ZodFirstPartyTypeKind.ZodUnknown:
return parseUnknownDef();
case ZodFirstPartyTypeKind.ZodDefault:
return parseDefaultDef(def, refs);
case ZodFirstPartyTypeKind.ZodBranded:
return parseBrandedDef(def, refs);
case ZodFirstPartyTypeKind.ZodReadonly:
return parseReadonlyDef(def, refs);
case ZodFirstPartyTypeKind.ZodCatch:
return parseCatchDef(def, refs);
case ZodFirstPartyTypeKind.ZodPipeline:
return parsePipelineDef(def, refs);
case ZodFirstPartyTypeKind.ZodFunction:
case ZodFirstPartyTypeKind.ZodVoid:
case ZodFirstPartyTypeKind.ZodSymbol:
return undefined;
default:
/* c8 ignore next */
return ((_: never) => undefined)(typeName);
}
};

const addMeta = (
def: ZodTypeDef,
refs: Refs,
Expand Down
66 changes: 66 additions & 0 deletions src/parseTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { JsonSchema7AnyType } from "./parsers/any.js";
import { JsonSchema7ArrayType } from "./parsers/array.js";
import { JsonSchema7BigintType } from "./parsers/bigint.js";
import { JsonSchema7BooleanType } from "./parsers/boolean.js";
import { JsonSchema7DateType } from "./parsers/date.js";
import { JsonSchema7EnumType } from "./parsers/enum.js";
import {
JsonSchema7AllOfType
} from "./parsers/intersection.js";
import { JsonSchema7LiteralType } from "./parsers/literal.js";
import { JsonSchema7MapType } from "./parsers/map.js";
import {
JsonSchema7NativeEnumType,
} from "./parsers/nativeEnum.js";
import { JsonSchema7NeverType } from "./parsers/never.js";
import { JsonSchema7NullType } from "./parsers/null.js";
import {
JsonSchema7NullableType,
} from "./parsers/nullable.js";
import { JsonSchema7NumberType } from "./parsers/number.js";
import { JsonSchema7ObjectType } from "./parsers/object.js";
import { JsonSchema7RecordType } from "./parsers/record.js";
import { JsonSchema7SetType } from "./parsers/set.js";
import { JsonSchema7StringType } from "./parsers/string.js";
import { JsonSchema7TupleType } from "./parsers/tuple.js";
import {
JsonSchema7UndefinedType
} from "./parsers/undefined.js";
import { JsonSchema7UnionType } from "./parsers/union.js";
import { JsonSchema7UnknownType } from "./parsers/unknown.js";

type JsonSchema7RefType = { $ref: string };
type JsonSchema7Meta = {
title?: string;
default?: any;
description?: string;
markdownDescription?: string;
};

export type JsonSchema7TypeUnion =
| JsonSchema7StringType
| JsonSchema7ArrayType
| JsonSchema7NumberType
| JsonSchema7BigintType
| JsonSchema7BooleanType
| JsonSchema7DateType
| JsonSchema7EnumType
| JsonSchema7LiteralType
| JsonSchema7NativeEnumType
| JsonSchema7NullType
| JsonSchema7NumberType
| JsonSchema7ObjectType
| JsonSchema7RecordType
| JsonSchema7TupleType
| JsonSchema7UnionType
| JsonSchema7UndefinedType
| JsonSchema7RefType
| JsonSchema7NeverType
| JsonSchema7MapType
| JsonSchema7AnyType
| JsonSchema7NullableType
| JsonSchema7AllOfType
| JsonSchema7UnknownType
| JsonSchema7SetType;

export type JsonSchema7Type = JsonSchema7TypeUnion & JsonSchema7Meta;
3 changes: 2 additions & 1 deletion src/parsers/array.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ZodArrayDef, ZodFirstPartyTypeKind } from "zod";
import { ErrorMessages, setResponseValueAndErrors } from "../errorMessages.js";
import { JsonSchema7Type, parseDef } from "../parseDef.js";
import { parseDef } from "../parseDef.js";
import { JsonSchema7Type } from "../parseTypes.js";
import { Refs } from "../Refs.js";

export type JsonSchema7ArrayType = {
Expand Down
3 changes: 2 additions & 1 deletion src/parsers/default.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ZodDefaultDef } from "zod";
import { JsonSchema7Type, parseDef } from "../parseDef.js";
import { parseDef } from "../parseDef.js";
import { JsonSchema7Type } from "../parseTypes.js";
import { Refs } from "../Refs.js";

export function parseDefaultDef(
Expand Down
3 changes: 2 additions & 1 deletion src/parsers/effects.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ZodEffectsDef } from "zod";
import { JsonSchema7Type, parseDef } from "../parseDef.js";
import { parseDef } from "../parseDef.js";
import { JsonSchema7Type } from "../parseTypes.js";
import { Refs } from "../Refs.js";

export function parseEffectsDef(
Expand Down
3 changes: 2 additions & 1 deletion src/parsers/intersection.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ZodIntersectionDef } from "zod";
import { JsonSchema7Type, parseDef } from "../parseDef.js";
import { parseDef } from "../parseDef.js";
import { JsonSchema7Type } from "../parseTypes.js";
import { Refs } from "../Refs.js";
import { JsonSchema7StringType } from "./string.js";

Expand Down
3 changes: 2 additions & 1 deletion src/parsers/map.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ZodMapDef } from "zod";
import { JsonSchema7Type, parseDef } from "../parseDef.js";
import { parseDef } from "../parseDef.js";
import { JsonSchema7Type } from "../parseTypes.js";
import { Refs } from "../Refs.js";
import { JsonSchema7RecordType, parseRecordDef } from "./record.js";

Expand Down
3 changes: 2 additions & 1 deletion src/parsers/nullable.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ZodNullableDef } from "zod";
import { JsonSchema7Type, parseDef } from "../parseDef.js";
import { parseDef } from "../parseDef.js";
import { JsonSchema7Type } from "../parseTypes.js";
import { Refs } from "../Refs.js";
import { JsonSchema7NullType } from "./null.js";
import { primitiveMappings } from "./union.js";
Expand Down
3 changes: 2 additions & 1 deletion src/parsers/object.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ZodObjectDef, ZodOptional } from "zod";
import { JsonSchema7Type, parseDef } from "../parseDef.js";
import { parseDef } from "../parseDef.js";
import { JsonSchema7Type } from "../parseTypes.js";
import { Refs } from "../Refs.js";

function decideAdditionalProperties(def: ZodObjectDef, refs: Refs) {
Expand Down
3 changes: 2 additions & 1 deletion src/parsers/optional.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ZodOptionalDef } from "zod";
import { JsonSchema7Type, parseDef } from "../parseDef.js";
import { parseDef } from "../parseDef.js";
import { JsonSchema7Type } from "../parseTypes.js";
import { Refs } from "../Refs.js";

export const parseOptionalDef = (
Expand Down
3 changes: 2 additions & 1 deletion src/parsers/pipeline.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ZodPipelineDef } from "zod";
import { JsonSchema7Type, parseDef } from "../parseDef.js";
import { parseDef } from "../parseDef.js";
import { JsonSchema7Type } from "../parseTypes.js";
import { Refs } from "../Refs.js";
import { JsonSchema7AllOfType } from "./intersection.js";

Expand Down
3 changes: 2 additions & 1 deletion src/parsers/promise.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ZodPromiseDef } from "zod";
import { JsonSchema7Type, parseDef } from "../parseDef.js";
import { parseDef } from "../parseDef.js";
import { JsonSchema7Type } from "../parseTypes.js";
import { Refs } from "../Refs.js";

export function parsePromiseDef(
Expand Down
3 changes: 2 additions & 1 deletion src/parsers/record.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
ZodRecordDef,
ZodTypeAny,
} from "zod";
import { JsonSchema7Type, parseDef } from "../parseDef.js";
import { parseDef } from "../parseDef.js";
import { JsonSchema7Type } from "../parseTypes.js";
import { Refs } from "../Refs.js";
import { JsonSchema7EnumType } from "./enum.js";
import { JsonSchema7ObjectType } from "./object.js";
Expand Down
Loading

0 comments on commit 99cc467

Please sign in to comment.