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
72 changes: 41 additions & 31 deletions scripts/generate.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ async function main() {
const jsonSchema = JSON.parse(
schemaSrc.replaceAll("#/$defs/", "#/components/schemas/"),
);
addExperimentalTags(jsonSchema);
const schemaDefs = jsonSchema.$defs;

await createClient({
input: {
openapi: "3.1.0",
Expand All @@ -37,6 +40,7 @@ async function main() {
},
plugins: [
{
compatibilityVersion: 4,
name: "zod",
"~resolvers": createDeserializationResolvers(),
},
Expand All @@ -45,33 +49,11 @@ async function main() {
],
});

const schemaDefs = JSON.parse(
await fs.readFile("./schema/schema.json", "utf8"),
).$defs;

const zodPath = "./src/schema/zod.gen.ts";
const zodSrc = await fs.readFile(zodPath, "utf8");
const zod = await prettier.format(
updateDocs(
zodSrc
.replace(`from "zod"`, `from "zod/v4"`)
// Weird type issue
.replaceAll(
/z\.record\((?!z\.string\(\),\s*)([^)]+)\)/g,
"z.record(z.string(), $1)",
)
.replaceAll(
/z\.coerce\s*\.bigint\(\)\s*\.min\(BigInt\("-9223372036854775808"\),\s*\{\s*message:\s*"Invalid value: Expected int64 to be >= -9223372036854775808",\s*\}\s*\)\s*\.max\(BigInt\("9223372036854775807"\),\s*\{\s*message:\s*"Invalid value: Expected int64 to be <= 9223372036854775807",\s*\}\s*\)/gm,
"z.number()",
)
.replaceAll(
/z\.coerce\s*\.bigint\(\)\s*\.gte\(BigInt\(0\)\)\s*\.max\(BigInt\("18446744073709551615"\),\s*\{\s*message:\s*"Invalid value: Expected uint64 to be <= 18446744073709551615",\s*\}\s*\)/gm,
"z.number()",
),
schemaDefs,
),
{ parser: "typescript" },
);
const zod = await prettier.format(updateDocs(zodSrc, schemaDefs), {
parser: "typescript",
});
await fs.writeFile(zodPath, zod);

const tsPath = "./src/schema/types.gen.ts";
Expand Down Expand Up @@ -171,15 +153,30 @@ function updateDocs(src, schemaDefs) {
}
}

// Replace UNSTABLE comments with @experimental at the end of the comment block
result = result.replace(
/(\/\*\*[\s\S]*?\*\*UNSTABLE\*\*[\s\S]*?)(\n\s*)\*\//g,
"$1$2*$2* @experimental$2*/",
);

return result;
}

function addExperimentalTags(value) {
if (Array.isArray(value)) {
for (const item of value) addExperimentalTags(item);
return;
}

if (!value || typeof value !== "object") return;

if (
typeof value.description === "string" &&
value.description.includes("**UNSTABLE**") &&
!value.description.includes("@experimental")
) {
value.description += "\n\n@experimental";
}

for (const child of Object.values(value)) {
addExperimentalTags(child);
}
}

function createDeserializationResolvers() {
return {
array(ctx) {
Expand All @@ -201,6 +198,15 @@ function createDeserializationResolvers() {
return ctx.chain.current;
},

number(ctx) {
if (!shouldEmitNumberForBigIntFormat(ctx.schema.format)) {
return undefined;
}

ctx.chain.current = ctx.$(ctx.symbols.z).attr("number").call();
return ctx.chain.current;
},

object(ctx) {
if (!hasDefaultOnErrorProperties(ctx.schema)) return undefined;

Expand Down Expand Up @@ -248,6 +254,10 @@ function createDeserializationResolvers() {
};
}

function shouldEmitNumberForBigIntFormat(format) {
return format === "int64" || format === "uint64";
}

function childContext(ctx, ...segments) {
return {
path: ref([...fromRef(ctx.path), ...segments]),
Expand Down
57 changes: 23 additions & 34 deletions src/schema/zod.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
requiredDefaultOnError,
vecSkipError,
} from "../schema-deserialize.js";
import { z } from "zod/v4";
import * as z from "zod/v4";

/**
* **UNSTABLE**
Expand Down Expand Up @@ -400,13 +400,12 @@ export const zErrorCode = z.union([
z.literal(-32002),
z.literal(-32042),
z
.number()
.int()
.min(-2147483648, {
message: "Invalid value: Expected int32 to be >= -2147483648",
error: "Invalid value: Expected int32 to be >= -2147483648",
})
.max(2147483647, {
message: "Invalid value: Expected int32 to be <= 2147483647",
error: "Invalid value: Expected int32 to be <= 2147483647",
}),
]);

Expand Down Expand Up @@ -839,11 +838,10 @@ export const zNesDocumentDidSaveCapabilities = z.object({
export const zNesEditHistoryCapabilities = z.object({
_meta: z.record(z.string(), z.unknown()).nullish(),
maxCount: z
.number()
.int()
.gte(0)
.max(4294967295, {
message: "Invalid value: Expected uint32 to be <= 4294967295",
error: "Invalid value: Expected uint32 to be <= 4294967295",
})
.nullish(),
});
Expand All @@ -860,11 +858,11 @@ export const zNesEditHistoryEntry = z.object({
* A code excerpt from a file.
*/
export const zNesExcerpt = z.object({
endLine: z.number().int().gte(0).max(4294967295, {
message: "Invalid value: Expected uint32 to be <= 4294967295",
endLine: z.int().gte(0).max(4294967295, {
error: "Invalid value: Expected uint32 to be <= 4294967295",
}),
startLine: z.number().int().gte(0).max(4294967295, {
message: "Invalid value: Expected uint32 to be <= 4294967295",
startLine: z.int().gte(0).max(4294967295, {
error: "Invalid value: Expected uint32 to be <= 4294967295",
}),
text: z.string(),
});
Expand Down Expand Up @@ -898,11 +896,10 @@ export const zNesRecentFile = z.object({
export const zNesRecentFilesCapabilities = z.object({
_meta: z.record(z.string(), z.unknown()).nullish(),
maxCount: z
.number()
.int()
.gte(0)
.max(4294967295, {
message: "Invalid value: Expected uint32 to be <= 4294967295",
error: "Invalid value: Expected uint32 to be <= 4294967295",
})
.nullish(),
});
Expand Down Expand Up @@ -994,11 +991,10 @@ export const zNesTriggerKind = z.union([
export const zNesUserActionsCapabilities = z.object({
_meta: z.record(z.string(), z.unknown()).nullish(),
maxCount: z
.number()
.int()
.gte(0)
.max(4294967295, {
message: "Invalid value: Expected uint32 to be <= 4294967295",
error: "Invalid value: Expected uint32 to be <= 4294967295",
})
.nullish(),
});
Expand Down Expand Up @@ -1267,11 +1263,11 @@ export const zPlanUpdate = z.object({
* The meaning of `character` depends on the negotiated position encoding.
*/
export const zPosition = z.object({
character: z.number().int().gte(0).max(4294967295, {
message: "Invalid value: Expected uint32 to be <= 4294967295",
character: z.int().gte(0).max(4294967295, {
error: "Invalid value: Expected uint32 to be <= 4294967295",
}),
line: z.number().int().gte(0).max(4294967295, {
message: "Invalid value: Expected uint32 to be <= 4294967295",
line: z.int().gte(0).max(4294967295, {
error: "Invalid value: Expected uint32 to be <= 4294967295",
}),
});

Expand Down Expand Up @@ -1369,7 +1365,7 @@ export const zPromptCapabilities = z.object({
* This version is only bumped for breaking changes.
* Non-breaking changes should be introduced via capabilities.
*/
export const zProtocolVersion = z.number().int().gte(0).lte(65535);
export const zProtocolVersion = z.int().gte(0).lte(65535);

/**
* Request parameters for the initialize method.
Expand Down Expand Up @@ -2029,19 +2025,17 @@ export const zLoadSessionRequest = z.object({
export const zReadTextFileRequest = z.object({
_meta: z.record(z.string(), z.unknown()).nullish(),
limit: z
.number()
.int()
.gte(0)
.max(4294967295, {
message: "Invalid value: Expected uint32 to be <= 4294967295",
error: "Invalid value: Expected uint32 to be <= 4294967295",
})
.nullish(),
line: z
.number()
.int()
.gte(0)
.max(4294967295, {
message: "Invalid value: Expected uint32 to be <= 4294967295",
error: "Invalid value: Expected uint32 to be <= 4294967295",
})
.nullish(),
path: z.string(),
Expand Down Expand Up @@ -2374,19 +2368,17 @@ export const zStringPropertySchema = z.object({
enum: z.array(z.string()).nullish(),
format: zStringFormat.nullish(),
maxLength: z
.number()
.int()
.gte(0)
.max(4294967295, {
message: "Invalid value: Expected uint32 to be <= 4294967295",
error: "Invalid value: Expected uint32 to be <= 4294967295",
})
.nullish(),
minLength: z
.number()
.int()
.gte(0)
.max(4294967295, {
message: "Invalid value: Expected uint32 to be <= 4294967295",
error: "Invalid value: Expected uint32 to be <= 4294967295",
})
.nullish(),
oneOf: z.array(zEnumOption).nullish(),
Expand Down Expand Up @@ -2434,11 +2426,10 @@ export const zTerminal = z.object({
export const zTerminalExitStatus = z.object({
_meta: z.record(z.string(), z.unknown()).nullish(),
exitCode: z
.number()
.int()
.gte(0)
.max(4294967295, {
message: "Invalid value: Expected uint32 to be <= 4294967295",
error: "Invalid value: Expected uint32 to be <= 4294967295",
})
.nullish(),
signal: z.string().nullish(),
Expand Down Expand Up @@ -2808,7 +2799,7 @@ export const zElicitationUrlMode = z.intersection(
z.union([zElicitationSessionScope, zElicitationRequestScope]),
z.object({
elicitationId: zElicitationId,
url: z.string().url(),
url: z.url(),
}),
);

Expand All @@ -2823,11 +2814,10 @@ export const zElicitationUrlMode = z.intersection(
export const zToolCallLocation = z.object({
_meta: z.record(z.string(), z.unknown()).nullish(),
line: z
.number()
.int()
.gte(0)
.max(4294967295, {
message: "Invalid value: Expected uint32 to be <= 4294967295",
error: "Invalid value: Expected uint32 to be <= 4294967295",
})
.nullish(),
path: z.string(),
Expand Down Expand Up @@ -3282,11 +3272,10 @@ export const zWaitForTerminalExitRequest = z.object({
export const zWaitForTerminalExitResponse = z.object({
_meta: z.record(z.string(), z.unknown()).nullish(),
exitCode: z
.number()
.int()
.gte(0)
.max(4294967295, {
message: "Invalid value: Expected uint32 to be <= 4294967295",
error: "Invalid value: Expected uint32 to be <= 4294967295",
})
.nullish(),
signal: z.string().nullish(),
Expand Down