1
1
/* SPDX-FileCopyrightText: 2025-present Kriasoft */
2
2
/* SPDX-License-Identifier: MIT */
3
3
4
- import type { ZodObject , ZodRawShape , ZodTypeAny } from "zod" ;
4
+ import type { ZodLiteral , ZodObject , ZodRawShape , ZodTypeAny } from "zod" ;
5
5
import { z } from "zod" ;
6
6
7
7
/**
@@ -23,37 +23,164 @@ export const MessageSchema = z.object({
23
23
meta : MessageMetadataSchema ,
24
24
} ) ;
25
25
26
+ // -----------------------------------------------------------------------
27
+ // Type Definitions
28
+ // -----------------------------------------------------------------------
29
+
30
+ /**
31
+ * Type for a message schema with no payload
32
+ */
33
+ export type BaseMessageSchema < T extends string > = ZodObject < {
34
+ type : ZodLiteral < T > ;
35
+ meta : typeof MessageMetadataSchema ;
36
+ } > ;
37
+
38
+ /**
39
+ * Type for a message schema with a payload
40
+ */
41
+ export type PayloadMessageSchema <
42
+ T extends string ,
43
+ P extends ZodTypeAny
44
+ > = ZodObject < {
45
+ type : ZodLiteral < T > ;
46
+ meta : typeof MessageMetadataSchema ;
47
+ payload : P ;
48
+ } > ;
49
+
50
+ /**
51
+ * Type for a message schema with a custom meta object
52
+ */
53
+ export type MessageSchemaWithCustomMeta <
54
+ T extends string ,
55
+ M extends ZodRawShape
56
+ > = ZodObject < {
57
+ type : ZodLiteral < T > ;
58
+ meta : ZodObject < typeof MessageMetadataSchema . shape & M > ;
59
+ } > ;
60
+
61
+ /**
62
+ * Type for a message schema with a payload and custom meta object
63
+ */
64
+ export type PayloadMessageSchemaWithCustomMeta <
65
+ T extends string ,
66
+ P extends ZodTypeAny ,
67
+ M extends ZodRawShape
68
+ > = ZodObject < {
69
+ type : ZodLiteral < T > ;
70
+ meta : ZodObject < typeof MessageMetadataSchema . shape & M > ;
71
+ payload : P ;
72
+ } > ;
73
+
74
+ // -----------------------------------------------------------------------
75
+ // Function Overloads
76
+ // -----------------------------------------------------------------------
77
+
78
+ /**
79
+ * Creates a message schema with a literal type but no payload or custom metadata
80
+ */
81
+ export function messageSchema < T extends string > (
82
+ messageType : T
83
+ ) : BaseMessageSchema < T > ;
84
+
85
+ /**
86
+ * Creates a message schema with a literal type and a payload schema (object form)
87
+ */
88
+ export function messageSchema <
89
+ T extends string ,
90
+ P extends Record < string , ZodTypeAny >
91
+ > ( messageType : T , payload : P ) : PayloadMessageSchema < T , ZodObject < P > > ;
92
+
93
+ /**
94
+ * Creates a message schema with a literal type and a payload schema (ZodType form)
95
+ */
96
+ export function messageSchema < T extends string , P extends ZodTypeAny > (
97
+ messageType : T ,
98
+ payload : P
99
+ ) : PayloadMessageSchema < T , P > ;
100
+
101
+ /**
102
+ * Creates a message schema with a literal type and custom metadata
103
+ */
104
+ export function messageSchema < T extends string , M extends ZodRawShape > (
105
+ messageType : T ,
106
+ payload : undefined ,
107
+ meta : ZodObject < M >
108
+ ) : MessageSchemaWithCustomMeta < T , M > ;
109
+
110
+ /**
111
+ * Creates a message schema with a literal type, payload (object form), and custom metadata
112
+ */
113
+ export function messageSchema <
114
+ T extends string ,
115
+ P extends Record < string , ZodTypeAny > ,
116
+ M extends ZodRawShape
117
+ > (
118
+ messageType : T ,
119
+ payload : P ,
120
+ meta : ZodObject < M >
121
+ ) : PayloadMessageSchemaWithCustomMeta < T , ZodObject < P > , M > ;
122
+
123
+ /**
124
+ * Creates a message schema with a literal type, payload (ZodType form), and custom metadata
125
+ */
126
+ export function messageSchema <
127
+ T extends string ,
128
+ P extends ZodTypeAny ,
129
+ M extends ZodRawShape
130
+ > (
131
+ messageType : T ,
132
+ payload : P ,
133
+ meta : ZodObject < M >
134
+ ) : PayloadMessageSchemaWithCustomMeta < T , P , M > ;
135
+
136
+ // -----------------------------------------------------------------------
137
+ // Implementation
138
+ // -----------------------------------------------------------------------
139
+
26
140
/**
27
141
* A helper function to create specific WebSocket message schemas.
28
142
* It extends the base `MessageSchema`, setting a literal type, adding a payload schema,
29
143
* and optionally extending the metadata schema.
144
+ *
145
+ * Implementation for all overloads
30
146
*/
31
147
export function messageSchema <
32
- Payload extends Record < string , ZodTypeAny > | ZodTypeAny | undefined ,
33
- Metadata extends ZodRawShape | undefined = undefined
148
+ T extends string ,
149
+ P extends Record < string , ZodTypeAny > | ZodTypeAny | undefined = undefined ,
150
+ M extends ZodRawShape = { }
34
151
> (
35
- messageType : string ,
36
- schema ?: Payload ,
37
- meta ?: Metadata extends ZodRawShape ? ZodObject < Metadata > : undefined
38
- ) {
152
+ messageType : T ,
153
+ payload ?: P ,
154
+ meta ?: M extends { } ? undefined : ZodObject < M >
155
+ ) : P extends undefined
156
+ ? M extends { }
157
+ ? BaseMessageSchema < T >
158
+ : MessageSchemaWithCustomMeta < T , M >
159
+ : P extends Record < string , ZodTypeAny >
160
+ ? M extends { }
161
+ ? PayloadMessageSchema < T , ZodObject < P > >
162
+ : PayloadMessageSchemaWithCustomMeta < T , ZodObject < P > , M >
163
+ : M extends { }
164
+ ? PayloadMessageSchema < T , P & ZodTypeAny >
165
+ : PayloadMessageSchemaWithCustomMeta < T , P & ZodTypeAny , M > {
39
166
// Create base schema with type and meta
40
167
const baseSchema = MessageSchema . extend ( {
41
168
type : z . literal ( messageType ) ,
42
169
meta : meta
43
- ? MessageMetadataSchema . extend ( meta . shape )
170
+ ? MessageMetadataSchema . extend ( ( meta as ZodObject < any > ) . shape )
44
171
: MessageMetadataSchema ,
45
172
} ) ;
46
173
47
174
// If no payload schema provided, return without payload
48
- if ( schema === undefined ) {
49
- return baseSchema ;
175
+ if ( payload === undefined ) {
176
+ return baseSchema as any ;
50
177
}
51
178
52
179
// Add payload to schema based on input type
53
180
return baseSchema . extend ( {
54
181
payload :
55
- schema instanceof z . ZodType
56
- ? schema
57
- : z . object ( schema as Record < string , ZodTypeAny > ) ,
58
- } ) ;
182
+ payload instanceof z . ZodType
183
+ ? payload
184
+ : z . object ( payload as Record < string , ZodTypeAny > ) ,
185
+ } ) as any ;
59
186
}
0 commit comments