import { DataContext, EndFn, RealAny, SetItemType } from "../types/internal"; import { UsableMiddleware } from "./Middleware"; import HttpRequestContext from "./request/HttpRequestContext"; import WsOpenContext from "./request/WsOpenContext"; import WsMessageContext from "./request/WsMessageContext"; import WsCloseContext from "./request/WsCloseContext"; import Base from "./request/Base"; import { oas31 } from "openapi3-ts"; type Listeners, Context extends Record, Middlewares extends UsableMiddleware[] = []> = { httpRequest: Set<((ctr: DataContext<'HttpRequest', 'POST', HttpRequestContext, Middlewares>, end: EndFn, data: Data) => RealAny)>; httpRequestFinish: Set<((ctr: DataContext<'HttpRequest', 'POST', Base, Middlewares>, ms: number) => RealAny)>; wsOpen: Set<((ctr: DataContext<'WsOpen', 'GET', WsOpenContext<'open', Context>, Middlewares>, end: EndFn, data: Data) => RealAny)>; wsOpenFinish: Set<((ctr: DataContext<'WsOpen', 'GET', Base, Middlewares>, ms: number) => RealAny)>; wsMessage: Set<((ctr: DataContext<'WsMessage', 'GET', WsMessageContext, Middlewares>, end: EndFn, data: Data) => RealAny)>; wsMessageFinish: Set<((ctr: DataContext<'WsMessage', 'GET', Base, Middlewares>, ms: number) => RealAny)>; wsClose: Set<((ctr: DataContext<'WsClose', 'GET', WsCloseContext, Middlewares>, end: EndFn, data: Data) => RealAny)>; wsCloseFinish: Set<((ctr: DataContext<'WsClose', 'GET', Base, Middlewares>, ms: number) => RealAny)>; }; export default class Validator = {}, Context extends Record = {}, Middlewares extends UsableMiddleware[] = []> { private openApi; private openApiFn; private listeners; /** * Create a new Validator * @example * ``` * import { Server, Channel } from "rjweb-server" * import { Runtime } from "@rjweb/runtime-generic" * import { network, number } from "@rjweb/utils" * * const echo = new Channel() * * const server = new Server(Runtime, { * port: 8000 * }) * * const authorize = new server.Validator<{ password: string }>() * .http((ctr, end, data) => { * if (!ctr.headers.has('authorization')) return end(ctr.status(ctr.$status.BAD_REQUEST).print('Authorization Required')) * if (ctr.headers.get('authorization') !== data.password) return end(ctr.status(ctr.$status.UNAUTHORIZED).print('Authorization Required')) * }) * * const authorizeLast = new server.Validator<{ allowedIP: network.IPAddress }>() * .extend(authorize) * .context<{ * random: number * }>() * .http((ctr, end, data) => { * if (!ctr.client.ip.equals(data.allowedIP)) return end(ctr.status(ctr.$status.UNAUTHORIZED).print('Invalid IP')) * * ctr["@"].random = number.generate(0, 100) * }) * * server.path('/', (path) => path * .ws('/echo', (ws) => ws * .validate(authorize.use({ password: '123' })) * .onConnect((ctr) => { * ctr.subscribe(echo) * }) * .onMessage((ctr) => { * echo.send(ctr.rawMessage()) // will send the message to all subscribed sockets * }) * ) * .http('GET', '/last-echo', (http) => http * .validate(authorizeLast.use({ password: '123', allowedIP: new network.IPAddress('127.1') })) * .onRequest((ctr) => { * return ctr.print( * echo.last() + * `\n${ctr["@"].random}` * ) * }) * ) * ) * * server.start().then(() => console.log('Server Started!')) * ``` * @since 9.0.0 */ constructor(); /** * Add OpenAPI Documentation to all Endpoints using this Validator * @since 9.0.0 */ document(item: oas31.OperationObject | ((data: Data) => oas31.OperationObject)): this; /** * Add context variables to the validator, typescript only * @since 9.0.0 */ context>(): Validator; /** * Extend on another validator * @since 9.0.0 */ extend, _Data extends [any, any] = V extends Validator ? [Data, Context] : [{}, {}]>(validator: V): Validator; /** * Add a validation step for an http event * @since 9.0.0 */ httpRequest(handler: SetItemType['httpRequest']>): this; /** * Listen for an http finish event * @since 9.6.0 */ httpRequestFinish(handler: SetItemType['httpRequestFinish']>): this; /** * Add a validation step for a websocket open event * @since 9.0.0 */ wsOpen(handler: SetItemType['wsOpen']>): this; /** * Listen for a websocket open finish event * @since 9.6.0 */ wsOpenFinish(handler: SetItemType['wsOpenFinish']>): this; /** * Add a validation step for a websocket message event * @since 9.0.0 */ wsMessage(handler: SetItemType['wsMessage']>): this; /** * Listen for a websocket message finish event * @since 9.6.0 */ wsMessageFinish(handler: SetItemType['wsMessageFinish']>): this; /** * Add a validation step for a websocket close event * @since 9.0.0 */ wsClose(handler: SetItemType['wsClose']>): this; /** * Listen for a websocket close finish event * @since 9.6.0 */ wsCloseFinish(handler: SetItemType['wsCloseFinish']>): this; /** * Use the Validator * @since 9.0.0 */ use(data: Data): UsableValidator; } export type UsableValidator = {}> = { NOTICE: 'DO NOT CALL MANUALLY, THIS IS FOR RJWEB INTERNALLY'; data: Record; listeners: Listeners; context: Context; openApi: oas31.OperationObject; }; export {};