diff --git a/.changeset/eleven-corners-smash.md b/.changeset/eleven-corners-smash.md new file mode 100644 index 000000000..2dd847ea9 --- /dev/null +++ b/.changeset/eleven-corners-smash.md @@ -0,0 +1,5 @@ +--- +'@hono/node-ws': minor +--- + +load custom env when init diff --git a/packages/node-ws/src/index.test.ts b/packages/node-ws/src/index.test.ts index e7fd7a847..a9ad0e102 100644 --- a/packages/node-ws/src/index.test.ts +++ b/packages/node-ws/src/index.test.ts @@ -2,12 +2,20 @@ import { serve } from '@hono/node-server' // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore import type { ServerType } from '@hono/node-server/dist/types' -import { Hono } from 'hono' +import { Env, Hono, Context } from 'hono' import { cors } from 'hono/cors' import { HTTPException } from 'hono/http-exception' import type { WSMessageReceive } from 'hono/ws' import { WebSocket } from 'ws' import { createNodeWebSocket } from '.' +import type { IncomingMessage } from 'node:http' +import type { Http2ServerRequest } from 'node:http2' + +interface CustomEnv extends Env { + Bindings: { + customVar: string + } +} describe('WebSocket helper', () => { let app: Hono @@ -18,7 +26,10 @@ describe('WebSocket helper', () => { beforeEach(async () => { app = new Hono() - ;({ injectWebSocket, upgradeWebSocket, wss } = createNodeWebSocket({ app })) + const getEnv = (req: IncomingMessage | Http2ServerRequest) => { + return { customVar: req.headers.upgrade } + } + ;({ injectWebSocket, upgradeWebSocket, wss } = createNodeWebSocket({ app, getEnv })) server = await new Promise((resolve) => { const server = serve({ fetch: app.fetch, port: 3030 }, () => { @@ -329,4 +340,17 @@ describe('WebSocket helper', () => { }) ) }) + + it('Should server can obtain environment variables', async () => { + const mainPromise = new Promise((resolve) => + app.get('/', (c: Context, next) => { + let ws = upgradeWebSocket((_c) => ({})) + resolve(c.env.customVar) + return ws(c, next) + }) + ) + + new WebSocket('ws://localhost:3030/') + expect(await mainPromise).toBe('websocket') + }) }) diff --git a/packages/node-ws/src/index.ts b/packages/node-ws/src/index.ts index f72441c7a..2a64ac734 100644 --- a/packages/node-ws/src/index.ts +++ b/packages/node-ws/src/index.ts @@ -1,11 +1,11 @@ -import type { Hono } from 'hono' +import type { Hono, Env } from 'hono' import { defineWebSocketHelper } from 'hono/ws' import type { UpgradeWebSocket, WSContext } from 'hono/ws' import type { WebSocket } from 'ws' import { WebSocketServer } from 'ws' import { STATUS_CODES } from 'node:http' import type { IncomingMessage, Server } from 'node:http' -import type { Http2SecureServer, Http2Server } from 'node:http2' +import type { Http2SecureServer, Http2Server, Http2ServerRequest } from 'node:http2' import type { Duplex } from 'node:stream' import { CloseEvent } from './events' @@ -23,6 +23,7 @@ export interface NodeWebSocketInit { // eslint-disable-next-line @typescript-eslint/no-explicit-any app: Hono baseUrl?: string | URL + getEnv?: (request: IncomingMessage | Http2ServerRequest) => Env['Bindings'] } const generateConnectionSymbol = () => Symbol('connection') @@ -70,11 +71,13 @@ export const createNodeWebSocket = (init: NodeWebSocketInit): NodeWebSocket => { headers.append(key, Array.isArray(value) ? value[0] : value) } + const customEnv = init.getEnv?.(request) ?? {} const env: { incoming: IncomingMessage outgoing: undefined [CONNECTION_SYMBOL_KEY]?: symbol } = { + ...customEnv, incoming: request, outgoing: undefined, }