Add Zod-backed control protocol schemas

This commit is contained in:
Timothy J. Aveni
2026-06-25 20:49:58 -07:00
parent 34bcd5d8d8
commit e827230d95
4 changed files with 1044 additions and 2052 deletions
+7
View File
@@ -13,6 +13,10 @@
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./rpc": {
"types": "./dist/rpc.d.ts",
"default": "./dist/rpc.js"
}
},
"scripts": {
@@ -23,5 +27,8 @@
"devDependencies": {
"@types/node": "^24",
"typescript": "^5.9.3"
},
"dependencies": {
"zod": "^4.3.6"
}
}
+878 -2052
View File
File diff suppressed because it is too large Load Diff
+151
View File
@@ -0,0 +1,151 @@
import z from "zod";
export const JsonRpcVersionSchema = z.literal("2.0");
export const JsonRpcIdSchema = z.union([
z.string().min(1),
z.number().finite(),
]);
export const JsonRpcIdempotencyMetadataSchema = z
.object({
idempotencyKey: z.string().min(1).optional(),
fingerprint: z.string().min(1).optional(),
})
.strict();
export const JsonRpcRequestSchema = z.object({
jsonrpc: JsonRpcVersionSchema,
id: JsonRpcIdSchema,
method: z.string().min(1),
params: z.unknown().optional(),
meta: JsonRpcIdempotencyMetadataSchema.optional(),
});
export const JsonRpcNotificationSchema = z.object({
jsonrpc: JsonRpcVersionSchema,
method: z.string().min(1),
params: z.unknown().optional(),
meta: JsonRpcIdempotencyMetadataSchema.optional(),
});
export const JsonRpcErrorObjectSchema = z.object({
code: z.number().int(),
message: z.string(),
data: z.unknown().optional(),
});
export const JsonRpcSuccessResponseSchema = z.object({
jsonrpc: JsonRpcVersionSchema,
id: JsonRpcIdSchema,
result: z.unknown().optional(),
});
export const JsonRpcErrorResponseSchema = z.object({
jsonrpc: JsonRpcVersionSchema,
id: JsonRpcIdSchema,
error: JsonRpcErrorObjectSchema,
});
export const JsonRpcResponseSchema = z.union([
JsonRpcSuccessResponseSchema,
JsonRpcErrorResponseSchema,
]);
export const JsonRpcMessageSchema = z.union([
JsonRpcRequestSchema,
JsonRpcNotificationSchema,
JsonRpcResponseSchema,
]);
export const JsonRpcBatchSchema = z.array(JsonRpcMessageSchema).min(1);
export const JsonRpcPayloadSchema = z.union([
JsonRpcMessageSchema,
JsonRpcBatchSchema,
]);
export type JsonRpcId = z.output<typeof JsonRpcIdSchema>;
export type JsonRpcIdempotencyMetadata = z.output<
typeof JsonRpcIdempotencyMetadataSchema
>;
export type JsonRpcRequest = z.output<typeof JsonRpcRequestSchema>;
export type JsonRpcNotification = z.output<typeof JsonRpcNotificationSchema>;
export type JsonRpcErrorObject = z.output<typeof JsonRpcErrorObjectSchema>;
export type JsonRpcSuccessResponse = z.output<
typeof JsonRpcSuccessResponseSchema
>;
export type JsonRpcErrorResponse = z.output<typeof JsonRpcErrorResponseSchema>;
export type JsonRpcResponse = z.output<typeof JsonRpcResponseSchema>;
export type JsonRpcMessage = z.output<typeof JsonRpcMessageSchema>;
export type JsonRpcPayload = z.output<typeof JsonRpcPayloadSchema>;
export const parseJsonRpcPayload = (value: unknown): JsonRpcPayload | null => {
const parsed = JsonRpcPayloadSchema.safeParse(value);
return parsed.success ? parsed.data : null;
};
export const makeJsonRpcRequest = ({
id,
method,
params,
meta,
}: {
id: JsonRpcId;
method: string;
params?: unknown;
meta?: JsonRpcIdempotencyMetadata;
}): JsonRpcRequest => ({
jsonrpc: "2.0",
id,
method,
...(params === undefined ? {} : { params }),
...(meta === undefined ? {} : { meta }),
});
export const makeJsonRpcNotification = ({
method,
params,
meta,
}: {
method: string;
params?: unknown;
meta?: JsonRpcIdempotencyMetadata;
}): JsonRpcNotification => ({
jsonrpc: "2.0",
method,
...(params === undefined ? {} : { params }),
...(meta === undefined ? {} : { meta }),
});
export const makeJsonRpcSuccessResponse = ({
id,
result,
}: {
id: JsonRpcId;
result?: unknown;
}): JsonRpcSuccessResponse => ({
jsonrpc: "2.0",
id,
...(result === undefined ? {} : { result }),
});
export const makeJsonRpcErrorResponse = ({
id,
code,
message,
data,
}: {
id: JsonRpcId;
code: number;
message: string;
data?: unknown;
}): JsonRpcErrorResponse => ({
jsonrpc: "2.0",
id,
error: {
code,
message,
...(data === undefined ? {} : { data }),
},
});
+8
View File
@@ -11,6 +11,7 @@ __metadata:
dependencies:
"@types/node": "npm:^24"
typescript: "npm:^5.9.3"
zod: "npm:^4.3.6"
languageName: unknown
linkType: soft
@@ -49,3 +50,10 @@ __metadata:
checksum: 10c0/85a79189113a238959d7a647368e4f7c5559c3a404ebdb8fc4488145ce9426fcd82252a844a302798dfc0e37e6fb178ff481ed03bc4caf634c5757d9ef43521d
languageName: node
linkType: hard
"zod@npm:^4.3.6":
version: 4.4.3
resolution: "zod@npm:4.4.3"
checksum: 10c0/7ea31b558e88f9faf44f31dd185e2e1cbf51fed3081787fb96cc2534749b50c0acfc6da7f0922a7353ed092dd358c7d50c28ea96c94d04af64191bd33152eca3
languageName: node
linkType: hard