diff --git a/.changeset/giant-papayas-taste.md b/.changeset/giant-papayas-taste.md new file mode 100644 index 00000000..541c8b41 --- /dev/null +++ b/.changeset/giant-papayas-taste.md @@ -0,0 +1,5 @@ +--- +'@hono/node-ws': patch +--- + +Adapter won't send Buffer as a MessageEvent. diff --git a/packages/cloudflare-access/src/index.ts b/packages/cloudflare-access/src/index.ts index 1a624128..0f1362c3 100644 --- a/packages/cloudflare-access/src/index.ts +++ b/packages/cloudflare-access/src/index.ts @@ -1,5 +1,5 @@ import type { Context } from 'hono' -import { getCookie } from 'hono/cookie'; +import { getCookie } from 'hono/cookie' import { createMiddleware } from 'hono/factory' import { HTTPException } from 'hono/http-exception' diff --git a/packages/node-ws/src/index.test.ts b/packages/node-ws/src/index.test.ts index 771f80d0..7240c42a 100644 --- a/packages/node-ws/src/index.test.ts +++ b/packages/node-ws/src/index.test.ts @@ -52,9 +52,7 @@ describe('WebSocket helper', () => { }) it('Should be rejected if upgradeWebSocket is not used', async () => { - app.get( - '/', (c)=>c.body('') - ) + app.get('/', (c) => c.body('')) { const ws = new WebSocket('ws://localhost:3030/') @@ -70,7 +68,8 @@ describe('WebSocket helper', () => { expect(await mainPromise).toBe(true) } - { //also should rejected on fallback + { + //also should rejected on fallback const ws = new WebSocket('ws://localhost:3030/notFound') const mainPromise = new Promise((resolve) => { ws.onerror = () => { @@ -202,11 +201,11 @@ describe('WebSocket helper', () => { ws.send(binaryData) const receivedMessage = await mainPromise - expect(receivedMessage).toBeInstanceOf(Buffer) - expect((receivedMessage as Buffer).byteLength).toBe(binaryData.length) + expect(receivedMessage).toBeInstanceOf(ArrayBuffer) + expect((receivedMessage as ArrayBuffer).byteLength).toBe(binaryData.length) binaryData.forEach((val, idx) => { - expect((receivedMessage as Buffer).at(idx)).toBe(val) + expect(new Uint8Array(receivedMessage as ArrayBuffer)[idx]).toBe(val) }) }) diff --git a/packages/node-ws/src/index.ts b/packages/node-ws/src/index.ts index bea96bb9..e86b432a 100644 --- a/packages/node-ws/src/index.ts +++ b/packages/node-ws/src/index.ts @@ -25,7 +25,10 @@ export interface NodeWebSocketInit { */ export const createNodeWebSocket = (init: NodeWebSocketInit): NodeWebSocket => { const wss = new WebSocketServer({ noServer: true }) - const waiterMap = new Map void, response: Response }>() + const waiterMap = new Map< + IncomingMessage, + { resolve: (ws: WebSocket) => void; response: Response } + >() wss.on('connection', (ws, request) => { const waiter = waiterMap.get(request) @@ -64,9 +67,9 @@ export const createNodeWebSocket = (init: NodeWebSocketInit): NodeWebSocket => { if (!waiter || waiter.response !== response) { socket.end( 'HTTP/1.1 400 Bad Request\r\n' + - 'Connection: close\r\n' + - 'Content-Length: 0\r\n' + - '\r\n' + 'Connection: close\r\n' + + 'Content-Length: 0\r\n' + + '\r\n' ) waiterMap.delete(request) return @@ -113,7 +116,11 @@ export const createNodeWebSocket = (init: NodeWebSocketInit): NodeWebSocket => { for (const data of datas) { events.onMessage?.( new MessageEvent('message', { - data: isBinary ? data : data.toString('utf-8'), + data: isBinary + ? data instanceof ArrayBuffer + ? data + : data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) + : data.toString('utf-8'), }), ctx ) diff --git a/packages/oauth-providers/src/providers/twitch/authFlow.ts b/packages/oauth-providers/src/providers/twitch/authFlow.ts index 70d0317b..f342e2f0 100644 --- a/packages/oauth-providers/src/providers/twitch/authFlow.ts +++ b/packages/oauth-providers/src/providers/twitch/authFlow.ts @@ -77,13 +77,13 @@ export class AuthFlow { const url = 'https://id.twitch.tv/oauth2/token' - const response = (await fetch(url, { + const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: parsedOptions, - }).then((res) => res.json() as Promise)) + }).then((res) => res.json() as Promise) if ('error' in response) { throw new HTTPException(400, { message: response.error }) diff --git a/packages/oauth-providers/src/providers/twitch/refreshToken.ts b/packages/oauth-providers/src/providers/twitch/refreshToken.ts index 2e24c055..0e892f77 100644 --- a/packages/oauth-providers/src/providers/twitch/refreshToken.ts +++ b/packages/oauth-providers/src/providers/twitch/refreshToken.ts @@ -14,18 +14,18 @@ export async function refreshToken( client_secret, }) - const response = (await fetch('https://id.twitch.tv/oauth2/token', { + const response = await fetch('https://id.twitch.tv/oauth2/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: params, - }).then((res) => res.json() as Promise)) + }).then((res) => res.json() as Promise) if ('error' in response) { throw new HTTPException(400, { message: response.error }) } - + if ('message' in response) { throw new HTTPException(400, { message: response.message as string }) } diff --git a/packages/oauth-providers/src/providers/twitch/revokeToken.ts b/packages/oauth-providers/src/providers/twitch/revokeToken.ts index 1619506c..52b86ca7 100644 --- a/packages/oauth-providers/src/providers/twitch/revokeToken.ts +++ b/packages/oauth-providers/src/providers/twitch/revokeToken.ts @@ -2,10 +2,7 @@ import { HTTPException } from 'hono/http-exception' import { toQueryParams } from '../../utils/objectToQuery' import type { TwitchRevokingResponse } from './types' -export async function revokeToken( - client_id: string, - token: string -): Promise { +export async function revokeToken(client_id: string, token: string): Promise { const params = toQueryParams({ client_id: client_id, token, @@ -23,14 +20,16 @@ export async function revokeToken( if (!res.ok) { // Try to parse error response try { - const errorResponse = await res.json() as TwitchRevokingResponse + const errorResponse = (await res.json()) as TwitchRevokingResponse if (errorResponse && typeof errorResponse === 'object' && 'message' in errorResponse) { throw new HTTPException(400, { message: errorResponse.message }) } - // eslint-disable-next-line @typescript-eslint/no-unused-vars + // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (e) { // If parsing fails, throw a generic error with the status - throw new HTTPException(400, { message: `Token revocation failed with status: ${res.status}` }) + throw new HTTPException(400, { + message: `Token revocation failed with status: ${res.status}`, + }) } } diff --git a/packages/oauth-providers/src/providers/twitch/types.ts b/packages/oauth-providers/src/providers/twitch/types.ts index 23009d18..d3f44383 100644 --- a/packages/oauth-providers/src/providers/twitch/types.ts +++ b/packages/oauth-providers/src/providers/twitch/types.ts @@ -2,10 +2,10 @@ export type Scopes = // Analytics | 'analytics:read:extensions' | 'analytics:read:games' - + // Bits | 'bits:read' - + // Channel | 'channel:bot' | 'channel:manage:ads' @@ -85,11 +85,11 @@ export type Scopes = | 'moderator:read:vips' | 'moderator:read:warnings' | 'moderator:manage:warnings' - + // IRC Chat Scopes | 'chat:edit' | 'chat:read' - + // PubSub-specific Chat Scopes | 'whispers:read' @@ -110,7 +110,6 @@ export type TwitchRefreshError = Required> - // Success responses types from Twitch API export interface TwitchValidateSuccess { client_id: string @@ -150,19 +149,21 @@ export type TwitchTokenResponse = TwitchTokenSuccess | TwitchTokenError export type TwitchValidateResponse = TwitchValidateSuccess | TwitchValidateError export interface TwitchUserResponse { - data: [{ - id: string - login: string - display_name: string - type: string - broadcaster_type: string - description: string - profile_image_url: string - offline_image_url: string - view_count: number - email: string - created_at: string - }] + data: [ + { + id: string + login: string + display_name: string + type: string + broadcaster_type: string + description: string + profile_image_url: string + offline_image_url: string + view_count: number + email: string + created_at: string + } + ] } export type TwitchUser = TwitchUserResponse['data'][0] diff --git a/packages/oauth-providers/src/providers/twitch/validateToken.ts b/packages/oauth-providers/src/providers/twitch/validateToken.ts index 8453628b..b82fb388 100644 --- a/packages/oauth-providers/src/providers/twitch/validateToken.ts +++ b/packages/oauth-providers/src/providers/twitch/validateToken.ts @@ -1,14 +1,11 @@ import { HTTPException } from 'hono/http-exception' import type { TwitchValidateResponse } from './types' -export async function validateToken( - token: string -): Promise { - +export async function validateToken(token: string): Promise { const response = await fetch('https://id.twitch.tv/oauth2/validate', { method: 'GET', headers: { - authorization: `Bearer ${token}`, + authorization: `Bearer ${token}`, }, }).then((res) => res.json() as Promise)