rjweb-server
Version:
Easy and Robust Way to create a Web Server with Many Easy-to-use Features in NodeJS
115 lines (114 loc) • 5.04 kB
TypeScript
import { DataContext, EndFn, RealAny } 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 { OperationObject } from "openapi3-ts/oas31";
type Listeners<Data extends Record<string, any>, Context extends Record<string, any>, Middlewares extends UsableMiddleware[] = []> = {
httpRequest: ((ctr: DataContext<'HttpRequest', 'POST', HttpRequestContext<Context>, Middlewares>, end: EndFn, data: Data) => RealAny)[];
wsOpen: ((ctr: DataContext<'WsOpen', 'GET', WsOpenContext<'open', Context>, Middlewares>, end: EndFn, data: Data) => RealAny)[];
wsMessage: ((ctr: DataContext<'WsMessage', 'GET', WsMessageContext<Context>, Middlewares>, end: EndFn, data: Data) => RealAny)[];
wsClose: ((ctr: DataContext<'WsClose', 'GET', WsCloseContext<Context>, Middlewares>, end: EndFn, data: Data) => RealAny)[];
};
export default class Validator<Data extends Record<string, any> = {}, Context extends Record<string, any> = {}, 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<string>()
*
* 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: OperationObject | ((data: Data) => OperationObject)): this;
/**
* Add context variables to the validator, typescript only
* @since 9.0.0
*/ context<NewContext extends Record<string, any>>(): Validator<Data, Context & NewContext, Middlewares>;
/**
* Extend on another validator
* @since 9.0.0
*/ extend<V extends Validator<any, any, any>, _Data extends [any, any] = V extends Validator<infer Data, infer Context> ? [Data, Context] : [{}, {}]>(validator: V): Validator<Data & _Data[0], Context & _Data[1]>;
/**
* Add a validation step for an http event
* @since 9.0.0
*/ httpRequest(handler: Listeners<Data, Context, Middlewares>['httpRequest'][number]): this;
/**
* Add a validation step for a websocket open event
* @since 9.0.0
*/ wsOpen(handler: Listeners<Data, Context, Middlewares>['wsOpen'][number]): this;
/**
* Add a validation step for a websocket message event
* @since 9.0.0
*/ wsMessage(handler: Listeners<Data, Context, Middlewares>['wsMessage'][number]): this;
/**
* Add a validation step for a websocket close event
* @since 9.0.0
*/ wsClose(handler: Listeners<Data, Context, Middlewares>['wsClose'][number]): this;
/**
* Use the Validator
* @since 9.0.0
*/ use(data: Data): UsableValidator<Context>;
}
export type UsableValidator<Context extends Record<string, any> = {}> = {
NOTICE: 'DO NOT CALL MANUALLY, THIS IS FOR RJWEB INTERNALLY';
data: Record<string, any>;
listeners: Listeners<any, any, any>;
context: Context;
openApi: OperationObject;
};
export {};