bun-ws-router
Version:
A simple and efficient WebSocket router for Bun with Zod/Valibot message validation.
91 lines • 4.74 kB
TypeScript
import * as v from "valibot";
import type { InferOutput, ObjectSchema } from "valibot";
/**
* Base schema for message metadata.
* Provides common fields that are available on all messages.
* Can be extended for specific message types.
*/
export declare const MessageMetadataSchema: v.ObjectSchema<{
readonly clientId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
readonly timestamp: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
readonly correlationId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
}, undefined>;
/**
* Base message schema that all specific message types extend.
* Defines the minimum structure required for routing.
*/
export declare const MessageSchema: v.ObjectSchema<{
readonly type: v.StringSchema<undefined>;
readonly meta: v.ObjectSchema<{
readonly clientId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
readonly timestamp: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
readonly correlationId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
}, undefined>;
}, undefined>;
/**
* Standard error codes for WebSocket communication.
* Used in ErrorMessage payloads for consistent error handling.
*/
export declare const ErrorCode: v.PicklistSchema<["INVALID_MESSAGE_FORMAT", "VALIDATION_FAILED", "UNSUPPORTED_MESSAGE_TYPE", "AUTHENTICATION_FAILED", "AUTHORIZATION_FAILED", "RESOURCE_NOT_FOUND", "RATE_LIMIT_EXCEEDED", "INTERNAL_SERVER_ERROR"], undefined>;
export type ErrorCode = InferOutput<typeof ErrorCode>;
/**
* Creates a type-safe WebSocket message schema with Valibot.
*
* The schema includes:
* - A literal type field for routing messages
* - Metadata for tracking client info and message context
* - Optional payload for the message data
*
* Types are fully inferred for use with WebSocketRouter handlers.
*/
export declare function messageSchema<T extends string>(messageType: T): ObjectSchema<{
type: v.LiteralSchema<T, T>;
meta: typeof MessageMetadataSchema;
}, undefined>;
export declare function messageSchema<T extends string, P extends v.BaseSchema<any, any, any>>(messageType: T, payload: P): ObjectSchema<{
type: v.LiteralSchema<T, T>;
meta: typeof MessageMetadataSchema;
payload: P;
}, undefined>;
export declare function messageSchema<T extends string, M extends ObjectSchema<any, any>>(messageType: T, payload: undefined, meta: M): ObjectSchema<{
type: v.LiteralSchema<T, T>;
meta: ObjectSchema<typeof MessageMetadataSchema.entries & M["entries"], undefined>;
}, undefined>;
export declare function messageSchema<T extends string, P extends v.BaseSchema<any, any, any>, M extends ObjectSchema<any, any>>(messageType: T, payload: P, meta: M): ObjectSchema<{
type: v.LiteralSchema<T, T>;
meta: ObjectSchema<typeof MessageMetadataSchema.entries & M["entries"], undefined>;
payload: P;
}, undefined>;
/**
* Standard error message schema for consistent error responses.
*/
export declare const ErrorMessage: v.ObjectSchema<{
type: v.LiteralSchema<"ERROR", "ERROR">;
meta: typeof MessageMetadataSchema;
payload: v.ObjectSchema<{
readonly code: v.PicklistSchema<["INVALID_MESSAGE_FORMAT", "VALIDATION_FAILED", "UNSUPPORTED_MESSAGE_TYPE", "AUTHENTICATION_FAILED", "AUTHORIZATION_FAILED", "RESOURCE_NOT_FOUND", "RATE_LIMIT_EXCEEDED", "INTERNAL_SERVER_ERROR"], undefined>;
readonly message: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
readonly context: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.AnySchema, undefined>, undefined>;
}, undefined>;
}, undefined>;
/**
* Creates a validated WebSocket message from a schema.
*
* @example
* ```typescript
* const EchoSchema = messageSchema("ECHO", v.object({ text: v.string() }));
* const message = createMessage(EchoSchema, { text: "Hello" });
*
* if (message.success) {
* ws.send(JSON.stringify(message.output));
* }
* ```
*/
export declare function createMessage<T extends MessageSchemaType>(schema: T, payload: T["entries"]["payload"] extends v.BaseSchema<unknown, unknown, v.BaseIssue<unknown>> ? InferOutput<T["entries"]["payload"]> : undefined, meta?: Partial<InferOutput<T["entries"]["meta"]>>): v.SafeParseResult<any>;
type MessageSchemaType = ObjectSchema<{
type: v.LiteralSchema<string, string>;
meta: v.BaseSchema<unknown, unknown, v.BaseIssue<unknown>>;
payload?: v.BaseSchema<unknown, unknown, v.BaseIssue<unknown>>;
}, undefined>;
export {};
//# sourceMappingURL=schema.d.ts.map