import Route from "../Route"; import { Method } from "../../types/global"; import Http from "./Http"; import { UsableMiddleware } from "../Middleware"; import { UsableValidator } from "../Validator"; import { LocationCallback, RateLimitConfig } from "../../types/internal"; import RateLimit from "./RateLimit"; import GlobalContext from "../../types/internal/classes/GlobalContext"; import { ArrayOrNot } from "@rjweb/utils"; import Ws from "./Ws"; import { oas31 } from "openapi3-ts"; export default class Path = {}, Excluded extends (keyof Path)[] = []> { private validators; protected routesHttp: Route<'http'>[]; protected routesStatic: Route<'static'>[]; protected routesWS: Route<'ws'>[]; protected _httpRatelimit: RateLimitConfig | null; protected _wsRatelimit: RateLimitConfig | null; protected promises: Promise[]; protected openApi: oas31.OperationObject; private _global; private prefix; private computePath; /** * Create a new Path * @since 6.0.0 */ constructor(prefix: string, global: GlobalContext, validators?: Validators, ratelimits?: [RateLimitConfig | null, RateLimitConfig | null], promises?: Promise[], openApi?: oas31.OperationObject); /** * Add OpenAPI Documentation to all HTTP Endpoints in this Path (and all children) * @since 9.0.0 */ document(item: oas31.OperationObject): Omit, Excluded[number] | 'document'>; /** * Add a Ratelimit to all HTTP Endpoints in this Path (and all children) * * When a User requests an Endpoint, that will count against their hit count, if * the hits exceeds the `` in `ms`, they wont be able to access * the route for `ms`. * @example * ``` * import { time } from "@rjweb/utils" * * server.path('/', (path) => path * .httpRateLimit((limit) => limit * .hits(5) * .window(time(20).s()) * .penalty(0) * ) // This will allow 5 requests every 20 seconds * .http('GET', '/hello', (ws) => ws * .onRequest(async(ctr) => { * ctr.print('Hello bro!') * }) * ) * ) * * server.rateLimit('httpRequest', (ctr) => { * ctr.print(`Please wait ${ctr.getRateLimit()?.resetIn}ms!!!!!`) * }) * ``` * @since 8.6.0 */ httpRatelimit(callback: (limit: RateLimit) => any): Omit, Excluded[number] | 'httpRatelimit'>; /** * Add a Ratelimit to all WebSocket Endpoints in this Path (and all children) * * When a User sends a message to a Socket, that will count against their hit count, if * the hits exceeds the `` in `ms`, they wont be able to access * the route for `ms`. * @example * ``` * import { time } from "@rjweb/utils" * * server.path('/', (path) => path * .httpRateLimit((limit) => limit * .hits(5) * .window(time(20).s()) * .penalty(0) * ) // This will allow 5 messages every 20 seconds * .ws('/echo', (ws) => ws * .onMessage(async(ctr) => { * ctr.print(await ctr.rawMessageBytes()) * }) * ) * ) * * server.rateLimit('wsMessage', (ctr) => { * ctr.print(`Please wait ${ctr.getRateLimit()?.resetIn}ms!!!!!`) * }) * ``` * @since 8.6.0 */ wsRatelimit(callback: (limit: RateLimit) => any): Omit, Excluded[number] | 'wsRatelimit'>; /** * Create a redirection route * @example * ``` * const server = new Server(...) * * server.path('/', (path) => path * .redirect('/google', 'https://google.com') * ) * ``` * @since 3.10.0 */ redirect(path: ArrayOrNot, redirect: string, type?: 'temporary' | 'permanent'): this; /** * Create a subpath of this Path * @since 6.0.0 */ path(prefix: ArrayOrNot | LocationCallback, callback: (path: Path) => any): this; /** * Use a Validator on all Endpoints in this Path * * This will attach a Validator to all Endpoints in this Path * @since 9.0.0 */ validate<_Validator extends UsableValidator>(validator: _Validator): Path; /** * Serve Static Files * @example * ``` * // All Files in "./public" will be served dynamically so they wont be loaded as routes by default * // Due to the stripHtmlEnding Option being on files will be served differently, /index.html -> /; /about.html -> /about; /contributors/index.html -> /contributors * const server = new Server(...) * * server.path('/', (path) => path * .static('./public', { * stripHtmlEnding: true // If enabled will remove .html ending from files * }) * ) * ``` * @since 3.1.0 */ static(folder: string, options?: { /** * Whether to automatically remove .html ending from files * @default false * @since 9.0.0 */ stripHtmlEnding?: boolean; /** * Whether to pre-process the files before serving them, * this will force you to restart the server every time * you add or remove a file. * @warning THIS WILL RECURSIVELY WALK THROUGH ALL FILES IN THE FOLDER, USE WITH CAUTION * @default false * @since 9.0.0 */ preProcessFiles?: boolean; }): this; /** * Add a new HTTP Route * @example * ``` * const server = new Server(...) * * server.path('/', (path) => path * .http('GET', '/hello', (ws) => ws * .onRequest((ctr) => { * ctr.print('Hello!') * }) * ) * ) * ``` * @since 6.0.0 */ http<_Method extends Method>(method: _Method, path: ArrayOrNot | LocationCallback, callback: (http: Http<_Method, Middlewares, Validators, Context>) => any): this; /** * Add a new WebSocket Route * @example * ``` * const server = new Server(...) * * server.path('/', (path) => path * .ws('/echo', (ws) => ws * .onMessage((ctr) => { * ctr.print(ctr.rawMessageBytes()) * }) * ) * ) * ``` * @since 6.0.0 */ ws(path: ArrayOrNot | LocationCallback, callback: (ws: Ws) => any): this; }