Skip to content

Commit f09861a

Browse files
committed
refactor: generateExample with strict parameter
1 parent bb61709 commit f09861a

File tree

2 files changed

+51
-39
lines changed

2 files changed

+51
-39
lines changed

src/utils/generateExample.test.ts

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe("generateExample", () => {
1010
email: z.string().email(),
1111
age: z.number().optional(),
1212
});
13-
expect(generateExample(schema, false)).toStrictEqual({
13+
expect(generateExample(schema, false, false)).toStrictEqual({
1414
id: 1,
1515
name: "example name",
1616
@@ -25,7 +25,7 @@ describe("generateExample", () => {
2525
email: z.string().email(),
2626
age: z.number().optional(),
2727
});
28-
expect(generateExample(schema, true)).toStrictEqual({
28+
expect(generateExample(schema, true, false)).toStrictEqual({
2929
id: 1,
3030
name: "example name",
3131
@@ -34,88 +34,94 @@ describe("generateExample", () => {
3434

3535
it("should generate an example from a zod string", () => {
3636
const schema = z.string();
37-
expect(generateExample(schema, false)).toBe("example string");
37+
expect(generateExample(schema, false, false)).toBe("example string");
3838
});
3939

4040
it("should generate an example from a zod number", () => {
4141
const schema = z.number();
42-
expect(generateExample(schema, false)).toBe(1);
43-
expect(generateExample(z.number().negative(), false)).toBe(-1);
44-
expect(generateExample(z.number().nonpositive(), false)).toBe(-1);
45-
expect(generateExample(z.number().multipleOf(7), false)).toBe(7);
42+
expect(generateExample(schema, false, false)).toBe(1);
43+
expect(generateExample(z.number().negative(), false, false)).toBe(-1);
44+
expect(generateExample(z.number().nonpositive(), false, false)).toBe(-1);
45+
expect(generateExample(z.number().multipleOf(7), false, false)).toBe(7);
4646
});
4747

4848
it("should return the minimum value from a zod number with minimum", () => {
4949
const schema = z.number().min(5);
50-
expect(generateExample(schema, false)).toBe(5);
50+
expect(generateExample(schema, false, false)).toBe(5);
5151
});
5252

5353
it("should generate an example from a zod integer", () => {
5454
const schema = z.bigint();
55-
expect(generateExample(schema, false)).toBe(1n);
55+
expect(generateExample(schema, false, false)).toBe(1n);
5656
});
5757

5858
it("should generate an example from a zod boolean", () => {
5959
const schema = z.boolean();
60-
expect(generateExample(schema, false)).toBe(false);
60+
expect(generateExample(schema, false, false)).toBe(false);
6161
});
6262

6363
it("should generate an example from a zod undefined", () => {
6464
const schema = z.undefined();
65-
expect(generateExample(schema, false)).toBe(undefined);
65+
expect(generateExample(schema, false, false)).toBe(undefined);
6666
});
6767

6868
it("should generate an example from a zod null", () => {
6969
const schema = z.null();
70-
expect(generateExample(schema, false)).toBe(null);
70+
expect(generateExample(schema, false, false)).toBe(null);
7171
});
7272

7373
it("should return the first item from a zod enum", () => {
7474
const schema = z.enum(["apple", "pear", "orange"]);
75-
expect(generateExample(schema, false)).toBe("apple");
75+
expect(generateExample(schema, false, false)).toBe("apple");
7676
});
7777

7878
it("should return the default value if the schema has one", () => {
7979
const schema = z.string().default("I think this function will be very useful");
80-
expect(generateExample(schema, false)).toBe("I think this function will be very useful");
80+
expect(generateExample(schema, false, false)).toBe("I think this function will be very useful");
8181
});
8282

8383
it("should handle zod string with special types", () => {
84-
expect(generateExample(z.string().email(), false)).toBe("[email protected]");
85-
expect(generateExample(z.string().url(), false)).toBe("https://example.com");
86-
expect(generateExample(z.string().emoji(), false)).toBe("😀");
87-
expect(generateExample(z.string().uuid(), false)).toBe("aa35d4a1-8f23-4cee-847c-2bfe89dc87c1");
88-
expect(generateExample(z.string().ip(), false)).toBe("192.168.1.1");
89-
expect(generateExample(z.string().datetime(), false)).toBe("2024-11-06T07:00:00.137Z");
90-
expect(generateExample(z.string().startsWith("openapi:"), false)).toBe("openapi:example");
91-
expect(generateExample(z.string().endsWith(":openapi"), false)).toBe("example:openapi");
84+
expect(generateExample(z.string().email(), false, false)).toBe("[email protected]");
85+
expect(generateExample(z.string().url(), false, false)).toBe("https://example.com");
86+
expect(generateExample(z.string().emoji(), false, false)).toBe("😀");
87+
expect(generateExample(z.string().uuid(), false, false)).toBe("aa35d4a1-8f23-4cee-847c-2bfe89dc87c1");
88+
expect(generateExample(z.string().ip(), false, false)).toBe("192.168.1.1");
89+
expect(generateExample(z.string().datetime(), false, false)).toBe("2024-11-06T07:00:00.137Z");
90+
expect(generateExample(z.string().startsWith("openapi:"), false, false)).toBe("openapi:example");
91+
expect(generateExample(z.string().endsWith(":openapi"), false, false)).toBe("example:openapi");
9292
});
9393

94-
it("should generate an example from a nullable zod string", () => {
94+
it("should generate an example from a nullable zod schema", () => {
9595
const schema = z.string().nullable();
96-
expect(generateExample(schema, false)).toBe("example nullable string");
96+
expect(generateExample(schema, false, false)).toBe("example nullable string");
97+
expect(generateExample(z.undefined().nullable(), false, false)).toBe(null);
9798
});
9899

99100
it("should return undefined from an optional zod string", () => {
100101
const schema = z.string().optional();
101-
expect(generateExample(schema, true)).toBe(undefined);
102+
expect(generateExample(schema, true, false)).toBe(undefined);
102103
});
103104

104105
it("should generate an example from a zod array", () => {
105-
expect(generateExample(z.string().array(), true)).toStrictEqual(["example string"]);
106-
expect(generateExample(z.number().array(), true)).toStrictEqual([1]);
107-
expect(generateExample(z.array(z.union([z.string(), z.number()])), true)).toStrictEqual(["example string", 1]);
106+
expect(generateExample(z.string().array(), true, false)).toStrictEqual(["example string"]);
107+
expect(generateExample(z.number().array(), true, false)).toStrictEqual([1]);
108+
expect(generateExample(z.array(z.union([z.string(), z.number()])), true, false)).toStrictEqual(["example string", 1]);
108109
});
109110

110111
it("should generate an example from a zod union", () => {
111112
const schema = z.union([z.string(), z.number()]);
112-
expect(generateExample(schema, true)).toBe("example string");
113+
expect(generateExample(schema, true, false)).toBe("example string");
113114
const emptyUnion = z.union([] as unknown as [ZodType, ZodType]);
114-
expect(generateExample(emptyUnion, true)).toBe(undefined);
115+
expect(generateExample(emptyUnion, true, false)).toBe(undefined);
115116
});
116117

117-
it("should throw an error from an unknown zod schema", () => {
118+
it("should throw an error for an unknown zod schema with strict option", () => {
118119
const schema = z.unknown();
119-
expect(() => generateExample(schema, false)).toThrow("Unknown zod schema");
120+
expect(() => generateExample(schema, false, true)).toThrow("Unknown zod schema");
121+
});
122+
123+
it("should return for an unknown zod schema without strict option", () => {
124+
const schema = z.unknown();
125+
expect(generateExample(schema, false, false)).toBe(undefined);
120126
});
121127
});

src/utils/generateExample.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ type ExampleGeneratorOptions = {
88
export default function generateExample<I, O>(
99
schema: ZodType<O, ZodTypeDef, I>,
1010
ignoreOptionals: boolean,
11+
strict: boolean,
1112
generatorOptions: ExampleGeneratorOptions = { nullable: false },
1213
): O {
1314
if ("defaultValue" in schema._def && typeof schema._def.defaultValue === "function") {
@@ -18,15 +19,17 @@ export default function generateExample<I, O>(
1819
if (ignoreOptionals) {
1920
return undefined as unknown as O;
2021
}
21-
return generateExample(innerSchema, ignoreOptionals, generatorOptions);
22+
return generateExample(innerSchema, ignoreOptionals, strict, generatorOptions);
2223
}
2324
if (schema instanceof ZodNullable) {
2425
const innerSchema = schema.unwrap();
25-
return (generateExample(innerSchema, ignoreOptionals, { ...generatorOptions, nullable: true }) ?? null) as unknown as O;
26+
const innerExample = generateExample(innerSchema, ignoreOptionals, strict, { ...generatorOptions, nullable: true });
27+
return (innerExample ?? null) as unknown as O;
2628
}
2729
if (schema instanceof ZodObject) {
2830
const entries = Object.entries(schema.shape).map(([keyName, childSchema]) => {
29-
return [keyName, generateExample(childSchema as ZodType, ignoreOptionals, { ...generatorOptions, keyName })] as const;
31+
const childExample = generateExample(childSchema as ZodType, ignoreOptionals, strict, { ...generatorOptions, keyName });
32+
return [keyName, childExample] as const;
3033
}).filter(([_, value]) => typeof value !== "undefined");
3134
return Object.fromEntries(entries) as unknown as O;
3235
}
@@ -106,17 +109,20 @@ export default function generateExample<I, O>(
106109
if (schema instanceof ZodArray) {
107110
if (schema._def.type instanceof ZodUnion) {
108111
const unionOptions = schema._def.type.options as ZodType[];
109-
return unionOptions.map(o => generateExample(o, ignoreOptionals, generatorOptions)) as unknown as O;
112+
return unionOptions.map(o => generateExample(o, ignoreOptionals, strict, generatorOptions)) as unknown as O;
110113
}
111-
return [generateExample(schema._def.type, ignoreOptionals, generatorOptions)] as unknown as O;
114+
return [generateExample(schema._def.type, ignoreOptionals, strict, generatorOptions)] as unknown as O;
112115
}
113116
if (schema instanceof ZodUnion) {
114117
const unionOptions = schema.options as ZodType[];
115118
const firstItem = unionOptions[0];
116119
if (firstItem) {
117-
return generateExample(firstItem, ignoreOptionals, generatorOptions);
120+
return generateExample(firstItem, ignoreOptionals, strict, generatorOptions);
118121
}
119122
return undefined as unknown as O;
120123
}
121-
throw new Error("Unknown zod schema");
124+
if (strict) {
125+
throw new Error("Unknown zod schema");
126+
}
127+
return undefined as unknown as O;
122128
}

0 commit comments

Comments
 (0)