Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions oxide-openapi-gen-ts/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion oxide-openapi-gen-ts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@oxide/openapi-gen-ts",
"version": "0.8.1",
"version": "0.9.0",
"description": "OpenAPI client generator used to generate Oxide TypeScript SDK",
"keywords": [
"oxide",
Expand Down
8 changes: 5 additions & 3 deletions oxide-openapi-gen-ts/src/client/msw-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function generateMSWHandlers(spec: OpenAPIV3.Document, destDir: string) {
type PathParams,
} from "msw";
import type { SnakeCasedPropertiesDeep as Snakify, Promisable } from "type-fest";
import { type ZodSchema } from "zod";
import { type ZodType } from "zod/v4";
import type * as Api from "./Api";
import { snakeify } from "./util";
import * as schema from "./validate";
Expand Down Expand Up @@ -105,7 +105,7 @@ export function generateMSWHandlers(spec: OpenAPIV3.Document, destDir: string) {
w("}");

w(`
function validateParams<S extends ZodSchema>(schema: S, req: Request, pathParams: PathParams) {
function validateParams<S extends ZodType>(schema: S, req: Request, pathParams: PathParams) {
const rawParams = new URLSearchParams(new URL(req.url).search)
const params: [string, unknown][] = []

Expand All @@ -131,7 +131,9 @@ export function generateMSWHandlers(spec: OpenAPIV3.Document, destDir: string) {
return { paramsErr: json({ error_code, message }, { status }) }
}

const handler = (handler: MSWHandlers[keyof MSWHandlers], paramSchema: ZodSchema | null, bodySchema: ZodSchema | null) =>
const handler = (handler: MSWHandlers[keyof MSWHandlers],
// eslint-disable-next-line @typescript-eslint/no-explicit-any
paramSchema: ZodType<any> | null, bodySchema: ZodType | null) =>
async ({
request: req,
params: pathParams,
Expand Down
2 changes: 1 addition & 1 deletion oxide-openapi-gen-ts/src/client/zodValidators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function generateZodValidators(

w(`/* eslint-disable */

import { z, ZodType } from 'zod';
import { z, ZodType } from 'zod/v4';
import { processResponseBody, uniqueItems } from './util';

/**
Expand Down
52 changes: 25 additions & 27 deletions oxide-openapi-gen-ts/src/schema/zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,33 +38,33 @@ export const schemaToZod = makeSchemaGenerator({
},

string(schema, { w0 }) {
w0(`z.string()`);

if ("default" in schema) {
w0(`.default(${JSON.stringify(schema.default)})`);
}
// Handle special formats that become standalone in Zod v4
if (schema.format === "uuid") {
w0(".uuid()");
}

if (schema.format === "ip") {
w0(".ip()");
w0("z.uuid()");
} else if (schema.format === "ip") {
// Generic IP becomes IPv4 for backward compatibility
w0("z.ipv4()");
} else if (schema.format === "ipv4") {
w0(".ip({ version: 'v4' })");
w0("z.ipv4()");
} else if (schema.format === "ipv6") {
w0(".ip({ version: 'v6' })");
}
w0("z.ipv6()");
} else {
// Regular string handling
w0(`z.string()`);

if ("minLength" in schema) {
w0(`.min(${schema.minLength})`);
}
if ("maxLength" in schema) {
w0(`.max(${schema.maxLength})`);
}
if ("pattern" in schema) {
w0(`.regex(${new RegExp(schema.pattern!).toString()})`);
if ("minLength" in schema) {
w0(`.min(${schema.minLength})`);
}
if ("maxLength" in schema) {
w0(`.max(${schema.maxLength})`);
}
if ("pattern" in schema) {
w0(`.regex(${new RegExp(schema.pattern!).toString()})`);
}
}

if (schema.nullable) w0(".nullable()");
if ("default" in schema) w0(`.default(${JSON.stringify(schema.default)})`);
},

date(schema, { w0 }) {
Expand Down Expand Up @@ -98,7 +98,7 @@ export const schemaToZod = makeSchemaGenerator({
const { w0, w } = io;
// record type, which only tells us the type of the values
if (!schema.properties || Object.keys(schema.properties).length === 0) {
w0("z.record(z.string().min(1),");
w0("z.record(z.string(),");
if (typeof schema.additionalProperties === "object") {
schemaToZod(schema.additionalProperties, io);
} else {
Expand Down Expand Up @@ -179,14 +179,12 @@ export const schemaToZod = makeSchemaGenerator({
w("])");
}

if ("default" in schema) {
w0(`.default(${JSON.stringify(schema.default)})`);
}
if (schema.nullable) io.w0(".nullable()");
if (schema.nullable) w0(".nullable()");
if ("default" in schema) w0(`.default(${JSON.stringify(schema.default)})`);
},

empty({ w0 }) {
w0("z.record(z.unknown())");
w0("z.record(z.string(), z.unknown())");
},

default(schema) {
Expand Down
Loading