diff --git a/README.md b/README.md index 99b03c8..740cbe2 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![CI](https://github.com/fastify/fastify-websocket/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/fastify/fastify-websocket/actions/workflows/ci.yml) [![NPM version](https://img.shields.io/npm/v/@fastify/websocket.svg?style=flat)](https://www.npmjs.com/package/@fastify/websocket) -[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://standardjs.com/) +[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-brightgreen?style=flat)](https://github.com/neostandard/neostandard) WebSocket support for [Fastify](https://github.com/fastify/fastify). Built upon [ws@8](https://www.npmjs.com/package/ws). diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..89fd678 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,6 @@ +'use strict' + +module.exports = require('neostandard')({ + ignores: require('neostandard').resolveIgnoresFromGitignore(), + ts: true +}) diff --git a/package.json b/package.json index 6ea08c5..29fdc97 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "type": "commonjs", "types": "types/index.d.ts", "scripts": { - "lint": "standard", + "lint": "eslint", + "lint:fix": "eslint --fix", "test": "npm run test:unit && npm run test:typescript", "test:unit": "tap", "test:typescript": "tsd" @@ -59,10 +60,11 @@ "@fastify/type-provider-typebox": "^5.0.0", "@types/node": "^22.0.0", "@types/ws": "^8.5.10", + "eslint": "^9.17.0", "fastify": "^5.0.0", "fastify-tsconfig": "^2.0.0", + "neostandard": "^0.12.0", "split2": "^4.2.0", - "standard": "^17.1.0", "tap": "^18.7.1", "tsd": "^0.31.0" }, diff --git a/types/index.d.ts b/types/index.d.ts index 52254a3..ea190d3 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,11 +1,11 @@ /// -import { IncomingMessage, ServerResponse, Server } from 'node:http'; -import { FastifyRequest, FastifyPluginCallback, RawServerBase, RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, RequestGenericInterface, ContextConfigDefault, FastifyInstance, FastifySchema, FastifyTypeProvider, FastifyTypeProviderDefault, FastifyBaseLogger } from 'fastify'; -import * as fastify from 'fastify'; -import * as WebSocket from 'ws'; -import { FastifyReply } from 'fastify/types/reply'; -import { preCloseHookHandler, preCloseAsyncHookHandler } from 'fastify/types/hooks'; -import { RouteGenericInterface } from 'fastify/types/route'; +import { IncomingMessage, ServerResponse, Server } from 'node:http' +import { FastifyRequest, FastifyPluginCallback, RawServerBase, RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, RequestGenericInterface, ContextConfigDefault, FastifyInstance, FastifySchema, FastifyTypeProvider, FastifyTypeProviderDefault, FastifyBaseLogger } from 'fastify' +import * as fastify from 'fastify' +import * as WebSocket from 'ws' +import { FastifyReply } from 'fastify/types/reply' +import { preCloseHookHandler, preCloseAsyncHookHandler } from 'fastify/types/hooks' +import { RouteGenericInterface } from 'fastify/types/route' interface WebsocketRouteOptions< RawServer extends RawServerBase = RawServerDefault, @@ -21,6 +21,7 @@ interface WebsocketRouteOptions< declare module 'fastify' { interface RouteShorthandOptions< + // eslint-disable-next-line @typescript-eslint/no-unused-vars RawServer extends RawServerBase = RawServerDefault > { websocket?: boolean; @@ -29,6 +30,7 @@ declare module 'fastify' { type InjectWSFn = ((path?: string, upgradeContext?: Partial) => Promise) + // eslint-disable-next-line @typescript-eslint/no-unused-vars interface FastifyInstance { websocketServer: WebSocket.Server, injectWS: InjectWSFn @@ -43,7 +45,7 @@ declare module 'fastify' { RawRequest extends RawRequestDefaultExpression = RawRequestDefaultExpression, RawReply extends RawReplyDefaultExpression = RawReplyDefaultExpression, TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault, - Logger extends FastifyBaseLogger = FastifyBaseLogger, + Logger extends FastifyBaseLogger = FastifyBaseLogger > { ( path: string, @@ -55,6 +57,7 @@ declare module 'fastify' { interface RouteOptions< RawServer extends RawServerBase = RawServerDefault, RawRequest extends RawRequestDefaultExpression = RawRequestDefaultExpression, + // eslint-disable-next-line @typescript-eslint/no-unused-vars RawReply extends RawReplyDefaultExpression = RawReplyDefaultExpression, RouteGeneric extends RouteGenericInterface = RouteGenericInterface, ContextConfig = ContextConfigDefault, @@ -64,11 +67,11 @@ declare module 'fastify' { > extends WebsocketRouteOptions { } } -type FastifyWebsocket = FastifyPluginCallback; +type FastifyWebsocket = FastifyPluginCallback declare namespace fastifyWebsocket { - interface WebSocketServerOptions extends Omit { } + interface WebSocketServerOptions extends Omit { } export type WebsocketHandler< RawServer extends RawServerBase = RawServerDefault, RawRequest extends RawRequestDefaultExpression = RawRequestDefaultExpression, @@ -81,7 +84,7 @@ declare namespace fastifyWebsocket { this: FastifyInstance, socket: WebSocket.WebSocket, request: FastifyRequest - ) => void | Promise; + ) => void | Promise export interface WebsocketPluginOptions { errorHandler?: (this: FastifyInstance, error: Error, socket: WebSocket.WebSocket, request: FastifyRequest, reply: FastifyReply) => void; options?: WebSocketServerOptions; @@ -98,11 +101,11 @@ declare namespace fastifyWebsocket { Logger extends FastifyBaseLogger = FastifyBaseLogger > extends fastify.RouteOptions, WebsocketRouteOptions { } - export type WebSocket = WebSocket.WebSocket; + export type WebSocket = WebSocket.WebSocket export const fastifyWebsocket: FastifyWebsocket export { fastifyWebsocket as default } } -declare function fastifyWebsocket(...params: Parameters): ReturnType +declare function fastifyWebsocket (...params: Parameters): ReturnType export = fastifyWebsocket diff --git a/types/index.test-d.ts b/types/index.test-d.ts index 8ee8555..4a8dff8 100644 --- a/types/index.test-d.ts +++ b/types/index.test-d.ts @@ -1,116 +1,114 @@ -import fastifyWebsocket, { WebsocketHandler, fastifyWebsocket as namedFastifyWebsocket, default as defaultFastifyWebsocket, WebSocket } from '..'; -import type { IncomingMessage } from "http"; -import fastify, { RouteOptions, FastifyRequest, FastifyInstance, FastifyReply, RequestGenericInterface, FastifyBaseLogger, RawServerDefault, FastifySchema, RawRequestDefaultExpression } from 'fastify'; -import { expectType } from 'tsd'; -import { Server } from 'ws'; -import { RouteGenericInterface } from 'fastify/types/route'; -import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'; +// eslint-disable-next-line import-x/no-named-default -- Testing default export +import fastifyWebsocket, { WebsocketHandler, fastifyWebsocket as namedFastifyWebsocket, default as defaultFastifyWebsocket, WebSocket } from '..' +import type { IncomingMessage } from 'http' +import fastify, { RouteOptions, FastifyRequest, FastifyInstance, FastifyReply, RequestGenericInterface, FastifyBaseLogger, RawServerDefault, FastifySchema, RawRequestDefaultExpression } from 'fastify' +import { expectType } from 'tsd' +import { Server } from 'ws' +import { RouteGenericInterface } from 'fastify/types/route' +import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox' import { Type } from '@sinclair/typebox' -const app: FastifyInstance = fastify(); -app.register(fastifyWebsocket); -app.register(fastifyWebsocket, {}); -app.register(fastifyWebsocket, { options: { maxPayload: 123 } }); +const app: FastifyInstance = fastify() +app.register(fastifyWebsocket) +app.register(fastifyWebsocket, {}) +app.register(fastifyWebsocket, { options: { maxPayload: 123 } }) app.register(fastifyWebsocket, { - errorHandler: function errorHandler(error: Error, socket: WebSocket, request: FastifyRequest, reply: FastifyReply): void { - expectType(this); + errorHandler: function errorHandler (error: Error, socket: WebSocket, request: FastifyRequest, reply: FastifyReply): void { + expectType(this) expectType(error) expectType(socket) expectType(request) expectType(reply) } -}); -app.register(fastifyWebsocket, { options: { perMessageDeflate: true } }); -app.register(fastifyWebsocket, { preClose: function syncPreclose() {} }); -app.register(fastifyWebsocket, { preClose: async function asyncPreclose(){} }); +}) +app.register(fastifyWebsocket, { options: { perMessageDeflate: true } }) +app.register(fastifyWebsocket, { preClose: function syncPreclose () {} }) +app.register(fastifyWebsocket, { preClose: async function asyncPreclose () {} }) app.get('/websockets-via-inferrence', { websocket: true }, async function (socket, request) { - expectType(this); - expectType(socket); - expectType(app.websocketServer); + expectType(this) + expectType(socket) + expectType(app.websocketServer) expectType>(request) - expectType(request.ws); - expectType(request.log); -}); + expectType(request.ws) + expectType(request.log) +}) const handler: WebsocketHandler = async (socket, request) => { - expectType(socket); - expectType(app.websocketServer); + expectType(socket) + expectType(app.websocketServer) expectType>(request) } -app.get('/websockets-via-annotated-const', { websocket: true }, handler); +app.get('/websockets-via-annotated-const', { websocket: true }, handler) app.get('/not-specifed', async (request, reply) => { - expectType(request); + expectType(request) expectType(reply) - expectType(request.ws); -}); + expectType(request.ws) +}) app.get('/not-websockets', { websocket: false }, async (request, reply) => { - expectType(request); - expectType(reply); -}); + expectType(request) + expectType(reply) +}) app.route({ method: 'GET', url: '/route-full-declaration-syntax', handler: (request, reply) => { - expectType(request); - expectType(reply); - expectType(request.ws); + expectType(request) + expectType(reply) + expectType(request.ws) }, wsHandler: (socket, request) => { - expectType(socket); - expectType>(request); - expectType(request.ws); + expectType(socket) + expectType>(request) + expectType(request.ws) }, -}); +}) const augmentedRouteOptions: RouteOptions = { method: 'GET', url: '/route-with-exported-augmented-route-options', handler: (request, reply) => { - expectType(request); - expectType(reply); + expectType(request) + expectType(reply) }, wsHandler: (socket, request) => { - expectType(socket); + expectType(socket) expectType>(request) }, -}; -app.route(augmentedRouteOptions); - +} +app.route(augmentedRouteOptions) app.get<{ Params: { foo: string }, Body: { bar: string }, Querystring: { search: string }, Headers: { auth: string } }>('/shorthand-explicit-types', { websocket: true }, async (socket, request) => { - expectType(socket); - expectType<{ foo: string }>(request.params); - expectType<{ bar: string }>(request.body); - expectType<{ search: string }>(request.query); - expectType< IncomingMessage['headers'] & { auth: string }>(request.headers); -}); - + expectType(socket) + expectType<{ foo: string }>(request.params) + expectType<{ bar: string }>(request.body) + expectType<{ search: string }>(request.query) + expectType< IncomingMessage['headers'] & { auth: string }>(request.headers) +}) app.route<{ Params: { foo: string }, Body: { bar: string }, Querystring: { search: string }, Headers: { auth: string } }>({ method: 'GET', url: '/longhand-explicit-types', handler: (request, _reply) => { - expectType<{ foo: string }>(request.params); - expectType<{ bar: string }>(request.body); - expectType<{ search: string }>(request.query); - expectType(request.headers); + expectType<{ foo: string }>(request.params) + expectType<{ bar: string }>(request.body) + expectType<{ search: string }>(request.query) + expectType(request.headers) }, wsHandler: (socket, request) => { - expectType(socket); - expectType<{ foo: string }>(request.params); - expectType<{ bar: string }>(request.body); - expectType<{ search: string }>(request.query); - expectType(request.headers); + expectType(socket) + expectType<{ foo: string }>(request.params) + expectType<{ bar: string }>(request.body) + expectType<{ search: string }>(request.query) + expectType(request.headers) }, -}); - +}) const schema = { params: Type.Object({ @@ -125,43 +123,42 @@ const schema = { headers: Type.Object({ auth: Type.String() }) -}; +} -const server = app.withTypeProvider(); +const server = app.withTypeProvider() server.route({ method: 'GET', url: '/longhand-type-inference', schema, handler: (request, _reply) => { - expectType<{ foo: string }>(request.params); - expectType<{ bar: string }>(request.body); - expectType<{ search: string }>(request.query); - expectType(request.headers); + expectType<{ foo: string }>(request.params) + expectType<{ bar: string }>(request.body) + expectType<{ search: string }>(request.query) + expectType(request.headers) }, wsHandler: (socket, request) => { - expectType(socket); - expectType<{ foo: string }>(request.params); - expectType<{ bar: string }>(request.body); - expectType<{ search: string }>(request.query); - expectType(request.headers); + expectType(socket) + expectType<{ foo: string }>(request.params) + expectType<{ bar: string }>(request.body) + expectType<{ search: string }>(request.query) + expectType(request.headers) }, -}); +}) server.get('/websockets-no-type-inference', { websocket: true }, async function (socket, request) { - expectType(this); - expectType(socket); - expectType(app.websocketServer); - expectType>(request); - expectType(request.ws); - expectType(request.params); - expectType(request.body); - expectType(request.query); - expectType(request.headers); - }); - - expectType(namedFastifyWebsocket); - expectType(defaultFastifyWebsocket); + expectType(this) + expectType(socket) + expectType(app.websocketServer) + expectType>(request) + expectType(request.ws) + expectType(request.params) + expectType(request.body) + expectType(request.query) + expectType(request.headers) + }) +expectType(namedFastifyWebsocket) +expectType(defaultFastifyWebsocket)