Skip to content

Commit 2b77667

Browse files
authored
Merge pull request #1187 from carlosmfreitas2409/main
fix: Websocket `beforeLoad` not being executed
2 parents a74b483 + f568eee commit 2b77667

File tree

4 files changed

+82
-9
lines changed

4 files changed

+82
-9
lines changed

src/adapter/bun/index.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,14 @@ export const BunAdapter: ElysiaAdapter = {
412412
normalize: app.config.normalize
413413
})
414414

415+
const validateUpgradeData = getSchemaValidator(options.upgradeData, {
416+
// @ts-expect-error private property
417+
modules: app.definitions.typebox,
418+
// @ts-expect-error private property
419+
models: app.definitions.type as Record<string, TSchema>,
420+
normalize: app.config.normalize
421+
})
422+
415423
app.route(
416424
'WS',
417425
path as any,
@@ -457,6 +465,12 @@ export const BunAdapter: ElysiaAdapter = {
457465

458466
let _id: string | undefined
459467

468+
let _beforeHandleData: any
469+
if (typeof options.beforeHandle === 'function') {
470+
const result = options.beforeHandle(context)
471+
_beforeHandleData = result instanceof Promise ? await result : result
472+
}
473+
460474
const errorHandlers = [
461475
...(Array.isArray(options.error)
462476
? options.error
@@ -502,11 +516,22 @@ export const BunAdapter: ElysiaAdapter = {
502516
options.pong?.(data)
503517
},
504518
open(ws: ServerWebSocket<any>) {
519+
if (validateUpgradeData?.Check(_beforeHandleData) === false) {
520+
return void ws.send(
521+
new ValidationError(
522+
'upgradeData',
523+
validateUpgradeData,
524+
_beforeHandleData
525+
).message as string
526+
)
527+
}
528+
505529
try {
506530
handleResponse(
507531
ws,
508532
options.open?.(
509-
new ElysiaWS(ws, context as any)
533+
new ElysiaWS(ws, context as any),
534+
_beforeHandleData as any
510535
)
511536
)
512537
} catch (error) {

src/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5424,7 +5424,8 @@ export default class Elysia<
54245424
MergeSchema<Ephemeral['schema'], Metadata['schema']>
54255425
>
54265426
>,
5427-
const Macro extends Metadata['macro']
5427+
const Macro extends Metadata['macro'],
5428+
const UpgradeDataSchema extends TSchema,
54285429
>(
54295430
path: Path,
54305431
options: WSLocalHook<
@@ -5436,7 +5437,8 @@ export default class Elysia<
54365437
Volatile['resolve'] &
54375438
MacroToContext<Metadata['macroFn'], Macro>
54385439
},
5439-
Macro
5440+
Macro,
5441+
UpgradeDataSchema
54405442
>
54415443
): Elysia<
54425444
BasePath,

src/ws/types.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { TSchema } from '@sinclair/typebox'
2+
13
import type { ElysiaWS } from './index'
24
import { WebSocketHandler } from './bun'
35

@@ -17,7 +19,8 @@ import {
1719
Prettify,
1820
RouteSchema,
1921
SingletonBase,
20-
TransformHandler
22+
TransformHandler,
23+
UnwrapSchema
2124
} from '../types'
2225

2326
type TypedWebSocketMethod =
@@ -33,10 +36,12 @@ export type FlattenResponse<Response extends RouteSchema['response']> =
3336

3437
interface TypedWebSocketHandler<
3538
in out Context,
36-
in out Route extends RouteSchema = {}
39+
in out Route extends RouteSchema = {},
40+
in out UpgradeDataSchema extends unknown = unknown
3741
> extends Omit<WebSocketHandler<Context>, TypedWebSocketMethod> {
3842
open?(
39-
ws: ElysiaWS<Context, Omit<Route, 'body'> & { body: never }>
43+
ws: ElysiaWS<Context, Omit<Route, 'body'> & { body: never }>,
44+
data: UpgradeDataSchema
4045
): MaybePromise<FlattenResponse<Route['response']> | void>
4146
message?(
4247
ws: ElysiaWS<Context, Route>,
@@ -118,13 +123,14 @@ export type WSParseHandler<Route extends RouteSchema, Context = {}> = (
118123
message: unknown
119124
) => MaybePromise<Route['body'] | void | undefined>
120125

121-
export type AnyWSLocalHook = WSLocalHook<any, any, any, any>
126+
export type AnyWSLocalHook = WSLocalHook<any, any, any, any, any>
122127

123128
export type WSLocalHook<
124129
LocalSchema extends InputSchema,
125130
Schema extends RouteSchema,
126131
Singleton extends SingletonBase,
127-
Macro extends MetadataBase['macro']
132+
Macro extends MetadataBase['macro'],
133+
UpgradeDataSchema extends TSchema,
128134
> = Prettify<Macro> &
129135
(LocalSchema extends any ? LocalSchema : Prettify<LocalSchema>) & {
130136
detail?: DocumentDecoration
@@ -134,6 +140,11 @@ export type WSLocalHook<
134140
upgrade?: Record<string, unknown> | ((context: Context) => unknown)
135141
parse?: MaybeArray<WSParseHandler<Schema>>
136142

143+
/**
144+
* Upgrade data's value
145+
*/
146+
upgradeData?: UpgradeDataSchema;
147+
137148
/**
138149
* Transform context's value
139150
*/
@@ -163,5 +174,6 @@ export type WSLocalHook<
163174
Omit<Context<Schema, Singleton>, 'body'> & {
164175
body: never
165176
},
166-
Schema
177+
Schema,
178+
UnwrapSchema<UpgradeDataSchema>
167179
>

test/ws/message.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,4 +487,38 @@ describe('WebSocket message', () => {
487487
await wsClosed(ws)
488488
app.stop()
489489
})
490+
491+
it('should call beforeHandle hook', async () => {
492+
const app = new Elysia()
493+
.ws('/ws', {
494+
upgradeData: t.Object({
495+
hello: t.String()
496+
}),
497+
beforeHandle() {
498+
return {
499+
hello: 'world'
500+
}
501+
},
502+
open(ws, data) {
503+
ws.send(data.hello)
504+
}
505+
})
506+
.listen(0)
507+
508+
const ws = newWebsocket(app.server!)
509+
510+
await wsOpen(ws)
511+
512+
const message = wsMessage(ws)
513+
514+
ws.send('Hello!')
515+
516+
const { data } = await message
517+
518+
expect(data).toBe('world')
519+
520+
await wsClosed(ws)
521+
522+
app.stop()
523+
})
490524
})

0 commit comments

Comments
 (0)