UNPKG

rjweb-server

Version:

Easy and Robust Way to create a Web Server with Many Easy-to-use Features in NodeJS

140 lines (139 loc) 4.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const utils_1 = require("@rjweb/utils"); class Validator { /** * 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() { this.openApi = {}; this.openApiFn = null; this.listeners = { httpRequest: [], wsOpen: [], wsMessage: [], wsClose: [] }; } /** * Add OpenAPI Documentation to all Endpoints using this Validator * @since 9.0.0 */ document(item) { if (typeof item !== 'function') this.openApi = utils_1.object.deepMerge(this.openApi, item); else this.openApiFn = item; return this; } /** * Add context variables to the validator, typescript only * @since 9.0.0 */ context() { return this; } /** * Extend on another validator * @since 9.0.0 */ extend(validator) { this.listeners.httpRequest.unshift(...validator.listeners.httpRequest); this.listeners.wsOpen.unshift(...validator.listeners.wsOpen); this.listeners.wsMessage.unshift(...validator.listeners.wsMessage); this.listeners.wsClose.unshift(...validator.listeners.wsClose); this.openApi = utils_1.object.deepMerge(this.openApi, validator.openApi); const openApiFn = this.openApiFn; if (validator.openApiFn) this.openApiFn = (data) => utils_1.object.deepMerge(openApiFn?.(data) ?? {}, validator.openApiFn?.(data) ?? {}); return this; } /** * Add a validation step for an http event * @since 9.0.0 */ httpRequest(handler) { this.listeners.httpRequest.push(handler); return this; } /** * Add a validation step for a websocket open event * @since 9.0.0 */ wsOpen(handler) { this.listeners.wsOpen.push(handler); return this; } /** * Add a validation step for a websocket message event * @since 9.0.0 */ wsMessage(handler) { this.listeners.wsMessage.push(handler); return this; } /** * Add a validation step for a websocket close event * @since 9.0.0 */ wsClose(handler) { this.listeners.wsClose.push(handler); return this; } /** * Use the Validator * @since 9.0.0 */ use(data) { return { data, listeners: this.listeners, openApi: utils_1.object.deepMerge(this.openApi, this.openApiFn?.(data) ?? {}), }; } } exports.default = Validator;