export = Client; /** * Typedef Imports * @typedef {import("../RestNio")} RestNio * @typedef {import("../util/RouteMap")} RouteMap * @typedef {import("../routes/Route")} Route * @typedef {import("../util/Options").ClientProperties} ClientProperties * @typedef {import("../util/Options").CookieOptions} CookieOptions */ /** * @exports Client * @class Client * @interface * @author 7kasper * @classdesc * Represents a client. * A client is either a http endpoint or websocket connection. * Clients share common functions so the routings can be interchangable. */ declare class Client { /** * Runs an async function inside a per-envelope context. The dispatcher * (e.g. {@link InterClient#routeEnvelope}) wraps `Client.run()` in this * so route handlers see the right `actor` / `effectivePermissions` even * across awaits, and concurrent envelopes don't clobber one another. * * Pass `{ actor: null, permissions: null }` to explicitly clear within a * sub-scope. * * @param {{actor: Object|null, permissions: PermissionSet|null}} ctx * @param {() => Promise<*>} fn * @returns {Promise<*>} */ static runEnvelopeContext(ctx: { actor: any | null; permissions: PermissionSet | null; }, fn: () => Promise): Promise; /** * @param {String} type - the client type. * @param {RestNio} restnio - reference to the server. * @param {Request} request - reference to the (instantiating) HTTP request. * @param {ClientProperties} [props] - optional properties about the client. * @param {String[]} [permissions] - optional set of permission the clients starts with. */ constructor(type: string, restnio: RestNio, request: Request, props?: ClientProperties, permissions?: string[]); type: string; restnio: import("../RestNio"); request: Request; props: any; permissions: PermissionSet; subscriptions: Set; token: {}; /** @type {(string | null)}*/ ip: (string | null); /** * Get all headers from the client. * NOTE: CURRENTLY ONLY HTTP SUPPORT * @type {Object.} */ headers: { [x: string]: string; }; /** * Get all cookies belonging to the client. * NOTE: CURRENTLY ONLY HTTP SUPPORT * @type {Object.} */ cookies: { [x: string]: string; }; /** * Per-client app-level state bag. RestNio never reads or writes this; * it is reserved entirely for route handlers to stash request-scoped * (HTTP) or connection-scoped (WS) data without colliding with internal * client fields. Common uses: buffered binary uploads, auth context, * feature flags, per-connection counters. * @type {Object.} */ state: { [x: string]: any; }; /** * Per-envelope actor context. Non-null only while a relayed envelope * carrying `_actor` is being dispatched on this client (and only when the * client is a trusted peer link — see {@link InterClient}). Carries the * upstream caller's identity claim: * * `{ sub?: string, perms?: string[], ...passthrough }` * * Route handlers that care about the original caller (auditing, logging, * downstream propagation) read it here; concurrency-safe across awaits * via `AsyncLocalStorage`. * * @returns {Object|null} */ get actor(): any | null; /** * Permission set used for the *current* route's permission check. When an * envelope carries `_actor` on a trusted peer link, this is the clamp of * the link's connection perms with the caller's claimed perms (see * {@link PermissionSet#intersect}). Otherwise falls back to the client's * own connection permissions. * * Use this if you want to perform an extra perm check inside a route * handler with the *same* effective set the dispatcher used. * * @returns {PermissionSet} */ get effectivePermissions(): PermissionSet; /** * Internal — placeholder kept for forward-compat. The previous * implementation routed `_type: 'sub.frame'` envelopes into a * {@link SubBridge}; that mechanism has been replaced by the * proxy-protocol shadow channels (see `lib/util/proxyDispatch`). * No reserved `_type` payloads are currently honored — the call returns * `false` so dispatch always falls through to path-based routing. * * @param {Object} _request * @returns {boolean} */ _dispatchTyped(_request: any): boolean; /** * Async startup after init of client. * Call this inside client implementation before setting up other async stuff. */ startBeat(): Promise; /** * Give the client access to all permissions granted by a valid token. * @param {string} JWT - the token to grant permissions with. * @throws {[number, string]} `[401, msg]` when the token is expired, * malformed or otherwise unverifiable — so clients get an * Unauthorized response (and can refresh / re-login) instead of a * generic 500. The thrown shape matches {@link Client#throwErr}. */ grantPermWithToken(token: any): Promise; /** * Checks whether a client has access to a certain permission. * @param {...string} perms - the permissions to check. * @returns true, if the client has the permission to do what is specified. */ hasPerm(...perms: string[]): boolean; /** * Give the client access to a certain permission. * Permissions are upgraded following the rules specifed in `PermissionSet.grant()` * @param {...string} perms - the permissions to grant. */ grantPerm(...perms: string[]): void; /** * Rovoke the client access to a certain permission. * Permissions are upgraded following the rules specifed in `PermissionSet.revoke()` * @param {...string} perms - the permissions to revoke. */ revokePerm(...perms: string[]): void; /** * Subscribe to a list with the name name. * @param {string} name - The name of the list subscribing to. */ subscribe(name: string): void; /** * Unsubscribe to a list with the name name. * @param {string} name - The name of the list unsubscribing from. */ unsubscribe(name: string): void; /** * Unsubscribe from all services. */ unsubscribeAll(): void; /** * Ok's a client. An ok is a typical response if a route was executed * but doesn't really return something. Websockets stay open on ok, * but the http implementation closes with a blank 200 status. */ ok(): void; /** * Sends an object to the client. * Strings will not be encoded, * buffers will be send with .buf() * other objects will be send as JSON strings. */ obj(obj: any): void; /** * Send all arguments specified with JSON encoding. */ json(...args: any[]): void; /** * Sends a plain string to the client. */ str(str: any): void; /** * Sends a buffer to the client. (Raw Bytes) * * Preferred alias: {@link Client#bin}. `buf` is retained for back-compat * and simply forwards to `bin` on concrete implementations. * @param {Buffer} buf */ buf(buf: Buffer): void; /** * Sends raw binary data to the client. * * - **HTTP:** writes the buffer to the response body. If no `content-type` * was set, defaults to `application/octet-stream`. For streaming, * multiple calls before `end()` are sent as chunked-encoding writes. * - **WebSocket:** sends a single binary frame. Can be called repeatedly * to stream multiple frames (for example when serving OTA firmware). * @param {Buffer} buf - the raw bytes to send. */ bin(buf: Buffer): void; /** * Sends an error + statuscode to the client. */ err(err: any, code: any): void; /** * Throws a client error in the neat way. * * A `[code, message]` tuple is sent as-is. Anything else (an Error, a * custom error class, a string) is first offered to the `'500'` route as * `{ error }` so the application can observe it (log, alert). If that * route responds - throws its own tuple or returns a value - that is the * reply. Otherwise the original error goes to the client unchanged * (`err.toString()`, status 500), exactly as before the hook existed. * @param {*} err - the thrown value. */ throwErr(err: any): Promise; _in500: boolean; /** * Closes the connection with a client. * * Walks the per-client proxy session table (populated by {@link * Router#proxy}) and informs each peer that this caller is going away, * so the corresponding callee-side {@link ProxyClient} can run its * `wsClose` lifecycle and drop subs. Without this notification, the * callee side would only learn about the disconnect when the outer * peer link itself dropped — leaking ProxyClients across api-client * churn while the central is healthy. */ close(): void; /** * Get or set a header property. * NOTE: CURRENTLY ONLY HTTP SUPPORT * @param {string} header - the header name to get / set. * @param {string} [value] - if specified the value to set in the header. */ header(header: string, value?: string): void; /** * Get or set a cookie :) * NOTE: CURRENTLY ONLY HTTP SUPPORT * @param {string} name - the name of the cookie to get / set. * @param {any} [value] - if specified, the value to set the cookie to. * @param {CookieOptions} [options] - if specified the cookie options. */ cookie(name: string, value?: any, options?: CookieOptions): void; /** * Clears a cookie. * NOTE: CURRENTLY ONLY HTTP SUPPORT * @param {string} name - the name of the cookie to clear. */ clearCookie(name: string): void; /** * Runs (finds and executes) a route or spits an error. * @param {string} routepath the path of the route. * @param {RouteMap} routeMap the map of routes to search in. * @param {Function} parser the parser to extract the params for the route. * @param {...any} parseParams the unparsed params for the route. */ run(routepath: string, routeMap: RouteMap, parser: Function, ...parseParams: any[]): Promise; lastroute: string; /** * Checks permissions, checks and formats params * and if everything is ok, executes the route. * @param {Route} route the route to execute * @param {Object} params the params to use in the route. * @returns true, if route returned something to client, * This return value is used to evaluate if the next route * should actually be executed. */ executeRoute(route: Route, params: any): Promise; } declare namespace Client { export { RestNio, RouteMap, Route, ClientProperties, CookieOptions }; } import PermissionSet = require("../util/PermissionSet"); /** * Typedef Imports */ type RestNio = import("../RestNio"); /** * Typedef Imports */ type RouteMap = import("../util/RouteMap"); /** * Typedef Imports */ type Route = import("../routes/Route"); /** * Typedef Imports */ type ClientProperties = import("../util/Options").ClientProperties; /** * Typedef Imports */ type CookieOptions = import("../util/Options").CookieOptions;