From 0b298ef7d7d7ee73f5cf0203d169c35ffb20c82f Mon Sep 17 00:00:00 2001 From: Miroir Framework Date: Mon, 27 Nov 2023 12:44:04 +0100 Subject: [PATCH] #1: ts conversion of object attributes become optional for mandatory attributes --- package.json | 6 +- src/JzodInterface.ts | 2 +- src/{Jzod.ts => JzodToZod.ts} | 113 ++++++++++++---------------- src/ZodToJzod.ts | 2 +- src/facade.ts | 2 +- src/index.ts | 2 +- tests/jzod.test.ts | 135 ++++++++++++++++++---------------- 7 files changed, 125 insertions(+), 137 deletions(-) rename src/{Jzod.ts => JzodToZod.ts} (87%) diff --git a/package.json b/package.json index 1674b6e..44425b7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@miroir-framework/jzod", "private": false, - "version": "0.5.4", + "version": "0.6.0", "description": "The Json bootstrapper for Zod.", "main": "dist/bundle.js", "types": "dist/bundle.d.ts", @@ -21,7 +21,7 @@ "@babel/plugin-transform-modules-commonjs": "^7.20.11", "@babel/preset-env": "^7.22.5", "@jest/globals": "^29.3.1", - "@miroir-framework/jzod-ts": "0.5.3", + "@miroir-framework/jzod-ts": "0.6.0", "@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-json": "^6.0.0", "@types/jest": "^29.2.4", @@ -31,7 +31,7 @@ "rollup-plugin-typescript2": "^0.34.1", "ts-jest": "^29.0.3", "tsconfig-paths": "^4.1.2", - "typescript": "^4.9.4", + "typescript": "5.0.3", "zod-to-json-schema": "^3.21.2", "zod-to-ts": "^1.2.0" } diff --git a/src/JzodInterface.ts b/src/JzodInterface.ts index 73c26e8..da91fa2 100644 --- a/src/JzodInterface.ts +++ b/src/JzodInterface.ts @@ -1,7 +1,7 @@ import { ZodTypeAny } from "zod"; -import { JzodElement, JzodReference } from "@miroir-framework/jzod-ts"; +import { JzodReference } from "@miroir-framework/jzod-ts"; export interface ZodSchemaAndDescription { diff --git a/src/Jzod.ts b/src/JzodToZod.ts similarity index 87% rename from src/Jzod.ts rename to src/JzodToZod.ts index 28cb165..a7de7bd 100644 --- a/src/Jzod.ts +++ b/src/JzodToZod.ts @@ -72,13 +72,13 @@ export function getContextZodSchemas(set: ZodSchemaAndDescriptionRecord) { // ###################################################################################################### function optionalNullableZodSchema(zodElement:ZodTypeAny, optional?: boolean, nullable?: boolean): ZodTypeAny { - const optionalElement = optional ? zodElement.optional() : zodElement; - const nullableElement = nullable ? optionalElement.nullable() : optionalElement; + const optionalElement: ZodTypeAny = optional ? zodElement.optional() : zodElement; + const nullableElement: ZodTypeAny = nullable ? optionalElement.nullable() : optionalElement; return nullableElement } function optionalNullableZodDescription(zodElement:string, optional?: boolean, nullable?: boolean): string { - const optionalElement = optional ? zodElement + ".optional()" : zodElement; - const nullableElement = nullable ? optionalElement + ".nullable()" : optionalElement; + const optionalElement: string = optional ? zodElement + ".optional()" : zodElement; + const nullableElement: string = nullable ? optionalElement + ".nullable()" : optionalElement; return nullableElement } @@ -88,7 +88,7 @@ export function jzodElementSchemaToZodSchemaAndDescription( element: JzodElement, getSchemaEagerReferences: () => ZodSchemaAndDescriptionRecord = () => ({}), getLazyReferences: () => ZodSchemaAndDescriptionRecord = () => ({}), - typeScriptLazyReferenceConverter?: (lazyZodSchema: ZodLazy, relativeReference: string | undefined) => ZodLazy + typeScriptLazyReferenceConverter?: (lazyZodSchema: ZodLazy, relativeReference: string | undefined) => any /** returns "any" to avoid pollution from zod-to-ts type "GetType", actual return type is ZodType & GetType */ ): ZodSchemaAndDescription { // console.log("jzodElementSchemaToZodSchemaAndDescription called for type",element.type); @@ -111,13 +111,11 @@ export function jzodElementSchemaToZodSchemaAndDescription( case "enum": { if (Array.isArray(element.definition) && element.definition.length > 1) { return { - zodSchema: optionalNullableZodSchema(z.enum([...element.definition] as any),element.optional,element.nullable), - zodText: optionalNullableZodDescription(`z.enum(${JSON.stringify([...element.definition])} as any)`, element.optional, element.nullable), + zodSchema: optionalNullableZodSchema((z.enum as any)([...element.definition]),element.optional,element.nullable),// avoiding to cast parameter to z.enum, since the cast impacts the generated zod schema + zodText: optionalNullableZodDescription(`z.enum(${JSON.stringify([...element.definition])})`, element.optional, element.nullable), }; } else { return { - // contextZodText: {}, - // contextZodSchema: {}, zodSchema: z.any(), zodText: `z.any()`, }; @@ -127,7 +125,6 @@ export function jzodElementSchemaToZodSchemaAndDescription( case "function": { const args = Object.entries(element.definition.args).map((e) => jzodElementSchemaToZodSchemaAndDescription( - // name, e[1], getSchemaEagerReferences, getLazyReferences, @@ -136,7 +133,6 @@ export function jzodElementSchemaToZodSchemaAndDescription( ); if (element.definition.returns) { const returns = jzodElementSchemaToZodSchemaAndDescription( - // name, element.definition.returns, getSchemaEagerReferences, getLazyReferences, @@ -145,9 +141,9 @@ export function jzodElementSchemaToZodSchemaAndDescription( return { contextZodText: undefined, // function definitions obfuscate any context defined within them contextZodSchema: undefined, - zodSchema: z + zodSchema: (z .function() - .args(...(args.map((z) => z.zodSchema) as any)) + .args as any)(...(args.map((z) => z.zodSchema))) // avoid casting the parameters to z.function().args(), since this cast impacts the produced zod schema .returns(returns.zodSchema), zodText: `z.function().args(${JSON.stringify(args.map((z) => z.zodText))}).returns(${ returns.zodText @@ -157,7 +153,7 @@ export function jzodElementSchemaToZodSchemaAndDescription( return { contextZodText: undefined, // function definitions obfuscate any context defined within them contextZodSchema: undefined, - zodSchema: z.function().args(...(args.map((z) => z.zodSchema) as any)), + zodSchema: (z.function().args as any)(...(args.map((z) => z.zodSchema))), //avoiding to type parameters to z.function().args, since this cast impacts the obtained zod schema zodText: `z.function().args(${JSON.stringify(args.map((z) => z.zodText))})`, }; } @@ -188,8 +184,6 @@ export function jzodElementSchemaToZodSchemaAndDescription( } case "literal": { return { - // contextZodText: {}, - // contextZodSchema: {}, zodSchema: optionalNullableZodSchema(z.literal(element.definition),element.optional,element.nullable), zodText: optionalNullableZodDescription(`z.literal("${element.definition}")`,element.optional,element.nullable), // TODO: defines only strings! }; @@ -197,12 +191,12 @@ export function jzodElementSchemaToZodSchemaAndDescription( } case "lazy": { const sub = jzodElementSchemaToZodSchemaAndDescription( - // name, element.definition, getSchemaEagerReferences, getLazyReferences, typeScriptLazyReferenceConverter ); + return { contextZodText: undefined, // lazy evaluation obfuscates any context defined within it contextZodSchema: undefined, @@ -213,14 +207,12 @@ export function jzodElementSchemaToZodSchemaAndDescription( } case "map": { const sub0 = jzodElementSchemaToZodSchemaAndDescription( - // name, element.definition[0], getSchemaEagerReferences, getLazyReferences, typeScriptLazyReferenceConverter ); const sub1 = jzodElementSchemaToZodSchemaAndDescription( - // name, element.definition[1], getSchemaEagerReferences, getLazyReferences, @@ -230,12 +222,11 @@ export function jzodElementSchemaToZodSchemaAndDescription( contextZodText: {...sub0.contextZodText, ...sub1.contextZodText}, contextZodSchema: {...sub0.contextZodSchema, ...sub1.contextZodSchema}, zodSchema: optionalNullableZodSchema(z.map(sub0.zodSchema,sub1.zodSchema),element.optional,element.nullable), - zodText: optionalNullableZodDescription(`z.set(${sub0.zodText},${sub1.zodText})`,element.optional,element.nullable), + zodText: optionalNullableZodDescription(`z.map(${sub0.zodText},${sub1.zodText})`,element.optional,element.nullable), }; break; } case "object": { - // console.log("1"); const extendsSubObject: ZodSchemaAndDescription | undefined = element.extend ? jzodElementSchemaToZodSchemaAndDescription( @@ -246,7 +237,6 @@ export function jzodElementSchemaToZodSchemaAndDescription( ) : undefined; - // console.log("2"); const definitionSubObject: ZodSchemaAndDescriptionRecord = Object.fromEntries( Object.entries(element.definition).map((a) => [ a[0], @@ -261,7 +251,6 @@ export function jzodElementSchemaToZodSchemaAndDescription( const schemas = Object.fromEntries(Object.entries(definitionSubObject).map((a) => [a[0], a[1].zodSchema])); const zodText = Object.fromEntries(Object.entries(definitionSubObject).map((a) => [a[0], a[1].zodText])); - // const schemasZodText = Object.fromEntries(Object.entries(definitionSubObject).map((a) => [a[0], zodToZodText(a[1].zodSchema, a[0])])); const contextZodText = getContextDescriptions(definitionSubObject); const contextZodSchema = getContextZodSchemas(definitionSubObject); @@ -279,6 +268,7 @@ export function jzodElementSchemaToZodSchemaAndDescription( // JSON.stringify(extendsSubObject), // "### definitionSubObject waaa", // JSON.stringify(definitionSubObject), + // (definitionSubObject["test"]?definitionSubObject["test"].zodSchema.isOptional():""), // // JSON.stringify(schemasZodText), // "### schemaEagerReferences", // JSON.stringify(getSchemaEagerReferences), @@ -377,17 +367,26 @@ export function jzodElementSchemaToZodSchemaAndDescription( * this call is avoided in this case, but this means Zod schemas used to generate typescript types must * not be used for validation purposes, please perform separate generations to accomodate each case. */ - // console.log("z.lazy called!!!!"); if (typeScriptLazyReferenceConverter) { - // - return z.any(); + /** + * in the case of TS conversion, this function is called, but the obtained jzod schema shall not be used for validation purposes! + * (the actual schema to be used is not known yet, since it's... lazy!). + */ + // return z.any(); // not working: this makes returned schema optional. + return z.never(); // all validations will fail } else { const lazyReferences = getLazyReferences(); + // console.log("JzodToZod when evaluating",element.definition,"got lazy references", lazyReferences); + if (element.definition.absolutePath && lazyReferences[element.definition.absolutePath]) { const absoluteRef = element.definition.absolutePath ? lazyReferences[element.definition.absolutePath].zodSchema : z.any(); - const relativeRef = element.definition.relativePath ? resolveEagerReference(element.definition.relativePath).zodSchema: absoluteRef + const relativeRef = element.definition.relativePath + ? element.definition.eager + ? resolveEagerReference(element.definition.relativePath).zodSchema + : lazyReferences[element.definition.relativePath].zodSchema + : absoluteRef; // const relativeRef = element.definition.relativePath ? resolveEagerReference(element.definition.relativePath,lazyReferences).zodSchema: absoluteRef return relativeRef; } else { @@ -417,8 +416,8 @@ export function jzodElementSchemaToZodSchemaAndDescription( const referenceResolvedSchema: ZodTypeAny = element.definition.eager ? eagerReference?.zodSchema??z.any() : typeScriptLazyReferenceConverter - ? typeScriptLazyReferenceConverter(lazyResolverZodSchema, element.definition.relativePath) - : lazyResolverZodSchema; + ? optionalNullableZodSchema(typeScriptLazyReferenceConverter(lazyResolverZodSchema, element.definition.relativePath), element.optional, element.nullable) + : optionalNullableZodSchema(lazyResolverZodSchema, element.optional, element.nullable); const referenceResolvedZodText = element.definition.eager ? optionalNullableZodDescription(`${eagerReference?.zodText}`, element.optional, element.nullable) @@ -438,8 +437,7 @@ export function jzodElementSchemaToZodSchemaAndDescription( // "contextSubObjectSchemaAndDescriptionRecord", // JSON.stringify(contextSubObjectSchemaAndDescriptionRecord), // "contextZodText", - // // JSON.stringify(contextZodText), - // JSON.stringify(contextReverseZodText), + // JSON.stringify(contextZodText), // "contextZodSchema", // JSON.stringify(contextZodSchema) // ); @@ -447,10 +445,6 @@ export function jzodElementSchemaToZodSchemaAndDescription( contextZodText: Object.keys(contextZodText).length > 0?contextZodText:undefined, contextZodSchema: Object.keys(contextZodSchema).length > 0?contextZodSchema:undefined, zodSchema: referenceResolvedSchema, - // zodSchema: typeScriptLazyReferenceConverter - // ? typeScriptLazyReferenceConverter(preResolveReference, element.definition.relativePath) - // : preResolveReference, - // zodText: optionalNullableZodDescription(`z.lazy(() =>${element.definition.relativePath})`,element.optional, element.nullable), // TODO: take lazy / eager resolution into account! zodText: referenceResolvedZodText }; return result; @@ -458,7 +452,6 @@ export function jzodElementSchemaToZodSchemaAndDescription( } case "set": { const sub = jzodElementSchemaToZodSchemaAndDescription( - // name, element.definition, getSchemaEagerReferences, getLazyReferences, @@ -498,7 +491,6 @@ export function jzodElementSchemaToZodSchemaAndDescription( ? optionalNullableZodSchema((z.coerce as any)[element.definition](), element.optional, element.nullable) : optionalNullableZodSchema((z as any)[element.definition](), element.optional, element.nullable) ; - // console.log("jzodElementSchemaToZodSchemaAndDescription simpleType",JSON.stringify(element),JSON.stringify(resultZodSchema)); return { contextZodText: undefined, contextZodSchema: undefined, @@ -519,13 +511,15 @@ export function jzodElementSchemaToZodSchemaAndDescription( typeScriptLazyReferenceConverter ) ); - - return { + + const subSchemas: [ZodTypeAny, ...ZodTypeAny[]] = [...subs.map((s:ZodSchemaAndDescription)=>s.zodSchema)] as [ZodTypeAny, ...ZodTypeAny[]] + const result = { contextZodSchema: subs.reduce((acc,curr)=>({...acc,...curr.contextZodText}),{}), contextZodText: subs.reduce((acc,curr)=>({...acc,...curr.contextZodSchema}),{}), - zodSchema: optionalNullableZodSchema(z.tuple([...subs.map(s=>s.zodSchema)] as any),element.optional,element.nullable), - zodText: optionalNullableZodDescription(`z.tuple(${JSON.stringify([...subs.map(s=>s.zodText)])} as any)`, element.optional, element.nullable), + zodSchema: optionalNullableZodSchema(z.tuple(subSchemas),element.optional,element.nullable), // avoid converting z.tuple() parameter to any, since this cast impacts resulting zod schema + zodText: optionalNullableZodDescription(`z.tuple(${objectToJsStringArray(subs.map((s) => s.zodText))})`, element.optional, element.nullable), }; + return result; } else { return { // contextZodText: {}, @@ -571,8 +565,16 @@ export function jzodElementSchemaToZodSchemaAndDescription( * TODO: DESCRIBE PROBLEM!!! */ - zodSchema: optionalNullableZodSchema(z.union(sub.map((s) => s.zodSchema) as any), element.optional, element.nullable), - zodText: optionalNullableZodDescription(`z.union(${objectToJsStringArray(sub.map((s) => s.zodText))})`, element.optional, element.nullable), + zodSchema: optionalNullableZodSchema( + (z.union as any)(sub.map((s) => s.zodSchema)), + element.optional, + element.nullable + ), // avoiding to cast parameter to z.union(), since this cast impacts the produced zod schema + zodText: optionalNullableZodDescription( + `z.union(${objectToJsStringArray(sub.map((s) => s.zodText))})`, + element.optional, + element.nullable + ), }; break; } @@ -636,31 +638,6 @@ export function referentialElementRelativeDependencies(element: JzodElement | Jz return result.filter((s) => s != "ZodSimpleBootstrapElementSchema"); } -// // ############################################################################################################## -// export function _zodSchemaToJsonSchema( -// referentialSchema: ZodSchemaAndDescription, -// dependencies: { [k: string]: string[] }, -// name?: string -// ): { [k: string]: any } { -// // const referentialSetEntries = Object.entries(referentialSchema); -// let result: { [k: string]: any } = {}; - -// for (const entry of referentialSetEntries) { -// const localDependencies = dependencies[entry[0]]; -// const localReferentialSet = Object.fromEntries( -// Object.entries(referentialSet) -// .filter((e) => (localDependencies && localDependencies.includes(e[0])) || e[0] == entry[0]) -// .map((e) => [e[0], e[1].zodSchema]) -// ); -// const convertedCurrent = zodToJsonSchema(entry[1].zodSchema, { -// $refStrategy: "relative", -// definitions: localReferentialSet, -// }); -// result[entry[0]] = convertedCurrent; -// } -// return result; -// } - // ############################################################################################################## export function _zodToJsonSchema( referentialSet: ZodSchemaAndDescriptionRecord, diff --git a/src/ZodToJzod.ts b/src/ZodToJzod.ts index 00cde77..86f0bf8 100644 --- a/src/ZodToJzod.ts +++ b/src/ZodToJzod.ts @@ -57,7 +57,7 @@ export const zodToJzod = (zod: ZodTypeAny, identifier: string): JzodElement => { // it is impossible to determine what the lazy value is referring to // so we force the user to declare it // if (!getTypeType) return createTypeReferenceFromString(identifier) - return { type: "schemaReference", definition: { relativePath: identifier } }; + return { type: "schemaReference", definition: { absolutePath: identifier } }; // TODO: how to restore absolutePath vs. relativePath vs. both? break; } case "ZodLiteral": { diff --git a/src/facade.ts b/src/facade.ts index 319afe0..5e93fc4 100644 --- a/src/facade.ts +++ b/src/facade.ts @@ -2,7 +2,7 @@ import ts from "typescript"; import { JzodElement } from "@miroir-framework/jzod-ts"; -import { jzodElementSchemaToZodSchemaAndDescription } from "./Jzod"; +import { jzodElementSchemaToZodSchemaAndDescription } from "./JzodToZod"; // export type TsTypeAliases = { // [k: string]: ts.TypeAliasDeclaration; diff --git a/src/index.ts b/src/index.ts index 4cb2966..8e41b97 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,7 +10,7 @@ export { getJsResultSetConstDeclarations, objectToJsStringArray, objectToJsStringObject, -} from "./Jzod" +} from "./JzodToZod" export { zodToJzod } from "./ZodToJzod" diff --git a/tests/jzod.test.ts b/tests/jzod.test.ts index ffba601..77c37b3 100644 --- a/tests/jzod.test.ts +++ b/tests/jzod.test.ts @@ -1,26 +1,18 @@ -import * as path from "path"; - -import { ZodLazy, ZodObject, ZodTypeAny, object, z } from "zod"; -import { createTypeAlias, printNode, withGetType, zodToTs } from "zod-to-ts"; +import { ZodObject, ZodTypeAny, z } from "zod"; import { - JzodElement, - jzodElement, - jzodToTsCode + JzodElement } from "@miroir-framework/jzod-ts"; -import { - jzodElementSchemaToZodSchemaAndDescription, -} from "../src/Jzod"; import { ZodSchemaAndDescription, ZodSchemaAndDescriptionRecord, jzodBootstrapElementSchema } from "../src/JzodInterface"; -import { zodCompare } from "../src/compare"; +import { + jzodElementSchemaToZodSchemaAndDescription, +} from "../src/JzodToZod"; import { zodToJzod } from "../src/ZodToJzod"; -import { jzodToZod } from "../src/facade"; -import { zodToZodText } from "../src/ZodToZodText"; import { convertZodSchemaToJsonSchemaAndWriteToFile } from "./utils"; @@ -50,14 +42,19 @@ function compareZodSchemas( testJzodSchemaZodSchemaAndDescription.zodSchema, undefined ); - // console.log("converted", convertedTest2JzodSchema); - // console.log("expected", referenceTest2ZodSchema); + // console.log("converted", convertedTestJsonSchema); + // console.log("expected", referenceTestJsonSchema); expect(convertedTestJsonSchema).toEqual(referenceTestJsonSchema); // console.log("#### done", testName); } + +// ################################################################################################ +// ################################################################################################ +// ################################################################################################ +// ################################################################################################ describe( 'Jzod', () => { @@ -259,6 +256,9 @@ describe( // } // ) + + + // ########################################################################################### it( 'jzod schema simple parsing', @@ -771,39 +771,50 @@ describe( it( "Jzod to Zod and back", async() => { + + const lazyRef:ZodSchemaAndDescription = jzodElementSchemaToZodSchemaAndDescription( + {type:"simpleType", definition: "string"}, + () => ({}) as ZodSchemaAndDescriptionRecord, + () => ({}) as ZodSchemaAndDescriptionRecord, + ); + const testZodToJzodConversion = ( typeName: string, testJzodSchema:JzodElement, + expectedZodSchemaText: string, expectedJzodSchema?: JzodElement, + ) => { - const testZodSchema:ZodSchemaAndDescription = jzodElementSchemaToZodSchemaAndDescription( + const testZodSchemaAndDescription:ZodSchemaAndDescription = jzodElementSchemaToZodSchemaAndDescription( testJzodSchema, () => ({}) as ZodSchemaAndDescriptionRecord, - () => ({}) as ZodSchemaAndDescriptionRecord, + () => ({lazyRef}) as ZodSchemaAndDescriptionRecord, ) - const testResult = zodToJzod(testZodSchema.zodSchema,typeName); - // console.log("Zod to Jzod testJzodSchema", typeName, JSON.stringify(testJzodSchema),"result",JSON.stringify(testResult)); + const testResult = zodToJzod(testZodSchemaAndDescription.zodSchema,typeName); + // console.log("Zod to Jzod testJzodSchema", typeName, "zod text", testZodSchemaAndDescription.zodText); + // console.log("Zod to Jzod testJzodSchema", typeName, "jzod result schema", JSON.stringify(testResult,undefined,2)); expect(testResult).toEqual(expectedJzodSchema??testJzodSchema); + expect(testZodSchemaAndDescription.zodText).toEqual(expectedZodSchemaText); } - testZodToJzodConversion("test1",{ type: "simpleType", definition: "any"}); - testZodToJzodConversion("test2",{ type: "simpleType", definition: "string", coerce: true }); - testZodToJzodConversion("test3",{ type: "simpleType", definition: "number"}); - testZodToJzodConversion("test4",{ type: "simpleType", definition: "bigint"}); - testZodToJzodConversion("test5",{ type: "simpleType", definition: "boolean"}); - testZodToJzodConversion("test6",{ type: "simpleType", definition: "date"}); - testZodToJzodConversion("test7",{ type: "simpleType", definition: "undefined"}); - testZodToJzodConversion("test8",{ type: "simpleType", definition: "unknown"}); - testZodToJzodConversion("test9",{ type: "simpleType", definition: "never"}); - testZodToJzodConversion("test11",{ type: "literal", definition: "test"}) - testZodToJzodConversion("test12",{ type: "array", definition: { type: "simpleType", definition: "any"}}) - testZodToJzodConversion("test13",{ type: "array", definition: { type: "simpleType", definition: "number"}}) - testZodToJzodConversion("test14",{ type: "array", definition: { type: "literal", definition: "number"}}) - testZodToJzodConversion("test15",{ type: "enum", definition: [ "a", "b", "c", "d" ] }) - testZodToJzodConversion("test16",{ type: "union", definition: [ { type: "simpleType", definition: "string"}, { type: "simpleType", definition: "number"} ] },) - testZodToJzodConversion("test17",{ type: "object", definition: { a: { type: "simpleType", definition: "string"}, b: { type: "simpleType", definition: "number"} } }) - testZodToJzodConversion("test18",{ type: "object", definition: { a: { type: "simpleType", definition: "string"}, b: { type: "simpleType", definition: "number", optional:true} } }) + testZodToJzodConversion("test1",{ type: "simpleType", definition: "any"}, "z.any()"); + testZodToJzodConversion("test2",{ type: "simpleType", definition: "string", coerce: true },"z.coerce.string()"); + testZodToJzodConversion("test3",{ type: "simpleType", definition: "number"},"z.number()"); + testZodToJzodConversion("test4",{ type: "simpleType", definition: "bigint"},"z.bigint()"); + testZodToJzodConversion("test5",{ type: "simpleType", definition: "boolean"},"z.boolean()"); + testZodToJzodConversion("test6",{ type: "simpleType", definition: "date"},"z.date()"); + testZodToJzodConversion("test7",{ type: "simpleType", definition: "undefined"},"z.undefined()"); + testZodToJzodConversion("test8",{ type: "simpleType", definition: "unknown"},"z.unknown()"); + testZodToJzodConversion("test9",{ type: "simpleType", definition: "never"},"z.never()"); + testZodToJzodConversion("test11",{ type: "literal", definition: "test"},"z.literal(\"test\")"); + testZodToJzodConversion("test12",{ type: "array", definition: { type: "simpleType", definition: "any"}}, "z.array(z.any())"); + testZodToJzodConversion("test13",{ type: "array", definition: { type: "simpleType", definition: "number"}}, "z.array(z.number())"); + testZodToJzodConversion("test14",{ type: "array", definition: { type: "literal", definition: "number"}}, "z.array(z.literal(\"number\"))"); + testZodToJzodConversion("test15",{ type: "enum", definition: [ "a", "b", "c", "d" ] }, "z.enum([\"a\",\"b\",\"c\",\"d\"])"); + testZodToJzodConversion("test16",{ type: "union", definition: [ { type: "simpleType", definition: "string"}, { type: "simpleType", definition: "number"} ] },"z.union([z.string(), z.number()])") + testZodToJzodConversion("test17",{ type: "object", definition: { a: { type: "simpleType", definition: "string"}, b: { type: "simpleType", definition: "number"} } }, "z.object({a:z.string(), b:z.number()}).strict()") + testZodToJzodConversion("test18",{ type: "object", definition: { a: { type: "simpleType", definition: "string"}, b: { type: "simpleType", definition: "number", optional:true} } },"z.object({a:z.string(), b:z.number().optional()}).strict()") testZodToJzodConversion( "test19", { @@ -814,6 +825,7 @@ describe( b: { type: "simpleType", definition: "number", optional: false }, }, }, + "z.object({a:z.string(), b:z.number()})", { type: "object", nonStrict: true, @@ -821,8 +833,10 @@ describe( a: { type: "simpleType", definition: "string" }, b: { type: "simpleType", definition: "number" }, }, - } + }, ); + + // no discriminated unions in Jzod const test20 = zodToJzod( z.discriminatedUnion("kind", [ z.object({ kind: z.literal("a"), a: z.string() }), @@ -856,37 +870,34 @@ describe( }, ], }); - testZodToJzodConversion("test21",{ type: "simpleType", definition: "boolean", optional: true}); - testZodToJzodConversion("test22",{ type: "simpleType", definition: "boolean", optional: false},{ type: "simpleType", definition: "boolean"}); - testZodToJzodConversion("test23",{ type: "simpleType", definition: "number", nullable: true}); - testZodToJzodConversion("test24",{ type: "simpleType", definition: "number", nullable: false},{ type: "simpleType", definition: "number"}); - testZodToJzodConversion("test25",{ type: "record", definition: {type: "simpleType", definition: "number"} }); - testZodToJzodConversion("test26",{ type: "tuple", definition: [ {type: "simpleType", definition: "number"}, {type: "simpleType", definition: "number"} ]}); + testZodToJzodConversion("test21",{ type: "simpleType", definition: "boolean", optional: true}, "z.boolean().optional()"); + testZodToJzodConversion("test22",{ type: "simpleType", definition: "boolean", optional: false},"z.boolean()", { type: "simpleType", definition: "boolean"}); + testZodToJzodConversion("test23",{ type: "simpleType", definition: "number", nullable: true}, "z.number().nullable()"); + testZodToJzodConversion("test24",{ type: "simpleType", definition: "number", nullable: false}, "z.number()", { type: "simpleType", definition: "number"}); + testZodToJzodConversion("test25",{ type: "record", definition: {type: "simpleType", definition: "number"} }, "z.record(z.string(),z.number())"); + testZodToJzodConversion( + "test26", + { + type: "tuple", + definition: [ + { type: "simpleType", definition: "number" }, + { type: "schemaReference", definition: { absolutePath: "test26" } }, + ], + }, + "z.tuple([z.number(), z.lazy(() =>undefined)])" + ); testZodToJzodConversion("test27", { type: "intersection", definition: { left: { type: "object", definition: { name: { type: "simpleType", definition: "string" } } }, right: { type: "object", definition: { role: { type: "simpleType", definition: "string" } } }, }, - }); - testZodToJzodConversion("test28",{ type: "map", definition: [ { type: "simpleType", definition: "string" }, { type: "simpleType", definition: "number" }]}); - testZodToJzodConversion("test29",{ type: "set", definition: { type: "simpleType", definition: "string" }}); - testZodToJzodConversion("test30",{ type: "schemaReference", definition: { relativePath: "test30" }}); - testZodToJzodConversion("test31",{ type: "function", definition: { args: [{ type: "simpleType", definition: "string" }], returns: { type: "simpleType", definition: "number" } }}); - testZodToJzodConversion("test32",{ type: "promise", definition: { type: "simpleType", definition: "string" }}); - // testZodToJzodConversion("test33", { - // type: "schemaReference", - // context: { - // a: { type: "simpleType", definition: "string" }, - // b: { - // type: "object", - // definition: { - // test: { type: "schemaReference", definition: { relativePath: "a" } }, - // }, - // }, - // }, - // definition: { relativePath: "b" }, - // }); + }, "z.intersection(z.object({name:z.string()}).strict(),z.object({role:z.string()}).strict())"); + testZodToJzodConversion("test28",{ type: "map", definition: [ { type: "simpleType", definition: "string" }, { type: "simpleType", definition: "number" }]}, "z.map(z.string(),z.number())"); + testZodToJzodConversion("test29",{ type: "set", definition: { type: "simpleType", definition: "string" }}, "z.set(z.string())"); + testZodToJzodConversion("test30",{ type: "schemaReference", definition: { absolutePath: "test30" }}, "z.lazy(() =>undefined)"); // schemaReference are not really convertible back to Jzod: the inner structure is lost when converting to Zod + testZodToJzodConversion("test31",{ type: "function", definition: { args: [{ type: "simpleType", definition: "string" }], returns: { type: "simpleType", definition: "number" } }}, "z.function().args([\"z.string()\"]).returns(z.number())"); + testZodToJzodConversion("test32",{ type: "promise", definition: { type: "simpleType", definition: "string" }}, "z.promise(z.string())"); } )