Add Zod-backed control protocol schemas
This commit is contained in:
@@ -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
File diff suppressed because it is too large
Load Diff
+151
@@ -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 }),
|
||||
},
|
||||
});
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user