Skip to content

Commit

Permalink
fix: autofix wrong schema.type case as QoL improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
astahmer committed Dec 12, 2022
1 parent 42d6f76 commit e589663
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 18 deletions.
2 changes: 1 addition & 1 deletion lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "openapi-zod-client",
"version": "1.4.12",
"version": "1.4.13",
"repository": {
"type": "git",
"url": "https://github.com/astahmer/openapi-zod-client.git"
Expand Down
19 changes: 10 additions & 9 deletions lib/src/openApiToTypescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,19 @@ TsConversionArgs): ts.Node | TypeDefinitionObject | string => {
return t.intersection(types);
}

if (schema.type && isPrimitiveType(schema.type)) {
const schemaType = schema.type ? (schema.type.toLowerCase() as NonNullable<typeof schema.type>) : undefined;
if (schemaType && isPrimitiveType(schemaType)) {
if (schema.enum) {
return t.union(schema.enum);
}

if (schema.type === "string") return t.string();
if (schema.type === "boolean") return t.boolean();
if (schema.type === "number" || schema.type === "integer") return t.number();
if (schema.type === "null") return t.reference("null");
if (schemaType === "string") return t.string();
if (schemaType === "boolean") return t.boolean();
if (schemaType === "number" || schemaType === "integer") return t.number();
if (schemaType === "null") return t.reference("null");
}

if (schema.type === "array") {
if (schemaType === "array") {
if (schema.items) {
let arrayOfType = getTypescriptFromOpenApi({ schema: schema.items, ctx, meta }) as TypeDefinition;
if (typeof arrayOfType === "string") {
Expand All @@ -119,7 +120,7 @@ TsConversionArgs): ts.Node | TypeDefinitionObject | string => {
return t.array(t.any());
}

if (schema.type === "object" || schema.properties || schema.additionalProperties) {
if (schemaType === "object" || schema.properties || schema.additionalProperties) {
if (!schema.properties) {
return {};
}
Expand Down Expand Up @@ -191,10 +192,10 @@ TsConversionArgs): ts.Node | TypeDefinitionObject | string => {
return t.type(inheritedMeta.name, t.reference("Partial", [objectType]));
}

if (!schema.type) return t.unknown();
if (!schemaType) return t.unknown();

// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw new Error(`Unsupported schema type: ${schema.type}`);
throw new Error(`Unsupported schema type: ${schemaType}`);
};

const tsResult = getTs();
Expand Down
15 changes: 8 additions & 7 deletions lib/src/openApiToZod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,10 @@ export function getZodSchema({ schema, ctx, meta: inheritedMeta, options }: Conv
return code.assign(`${first.toString()}.${rest}`);
}

if (schema.type && isPrimitiveType(schema.type)) {
const schemaType = schema.type ? (schema.type.toLowerCase() as NonNullable<typeof schema.type>) : undefined;
if (schemaType && isPrimitiveType(schemaType)) {
if (schema.enum) {
if (schema.type === "string") {
if (schemaType === "string") {
// eslint-disable-next-line sonarjs/no-nested-template-literals
return code.assign(`z.enum([${schema.enum.map((value) => `"${value}"`).join(", ")}])`);
}
Expand All @@ -115,7 +116,7 @@ export function getZodSchema({ schema, ctx, meta: inheritedMeta, options }: Conv
}

return code.assign(
match(schema.type)
match(schemaType)
.with("integer", () => "z.number()")
.with("string", () =>
match(schema.format)
Expand All @@ -126,15 +127,15 @@ export function getZodSchema({ schema, ctx, meta: inheritedMeta, options }: Conv
);
}

if (schema.type === "array") {
if (schemaType === "array") {
if (schema.items) {
return code.assign(`z.array(${getZodSchema({ schema: schema.items, ctx, meta, options }).toString()})`);
}

return code.assign("z.array(z.any())");
}

if (schema.type === "object" || schema.properties || schema.additionalProperties) {
if (schemaType === "object" || schema.properties || schema.additionalProperties) {
let additionalProps = "";
if (
(typeof schema.additionalProperties === "boolean" && schema.additionalProperties) ||
Expand Down Expand Up @@ -177,10 +178,10 @@ export function getZodSchema({ schema, ctx, meta: inheritedMeta, options }: Conv
return code.assign(`z.object(${properties})${isPartial ? ".partial()" : ""}${additionalProps}`);
}

if (!schema.type) return code.assign("z.unknown()");
if (!schemaType) return code.assign("z.unknown()");

// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw new Error(`Unsupported schema type: ${schema.type}`);
throw new Error(`Unsupported schema type: ${schemaType}`);
}

export const getZodChain = (schema: SchemaObject, meta?: CodeMetaData) => {
Expand Down
1 change: 0 additions & 1 deletion lib/tests/param-with-content.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { OpenAPIObject } from "openapi3-ts";
import { expect, test } from "vitest";
import { generateZodClientFromOpenAPI } from "../src";

// https://github.com/astahmer/openapi-zod-client/issues/49
test("param-with-content", async () => {
const openApiDoc: OpenAPIObject = {
openapi: "3.0.3",
Expand Down
47 changes: 47 additions & 0 deletions lib/tests/schema-type-wrong-case.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { OpenAPIObject } from "openapi3-ts";
import { expect, test } from "vitest";
import { generateZodClientFromOpenAPI } from "../src";

test("schema-type-wrong-case", async () => {
const openApiDoc: OpenAPIObject = {
openapi: "3.0.3",
info: { title: "Swagger Petstore - OpenAPI 3.0", version: "1.0.11" },
paths: {
"/pet": {
put: {
responses: {
"200": {
description: "Successful operation",
content: { "application/json": { schema: { $ref: "#/components/schemas/test1" } } },
},
},
},
},
},
components: {
schemas: {
test1: { type: "object", properties: { text1: { type: "Integer" as any } } },
},
},
};

const output = await generateZodClientFromOpenAPI({ disableWriteToFile: true, openApiDoc });
expect(output).toMatchInlineSnapshot(`
"import { makeApi, Zodios } from "@zodios/core";
import { z } from "zod";
const test1 = z.object({ text1: z.number() }).partial();
const endpoints = makeApi([
{
method: "put",
path: "/pet",
requestFormat: "json",
response: z.object({ text1: z.number() }).partial(),
},
]);
export const api = new Zodios(endpoints);
"
`);
});

0 comments on commit e589663

Please sign in to comment.