@bs-core/shell
Version:
The Bamboo Shell
507 lines (493 loc) • 18.4 kB
TypeScript
import * as crypto from 'crypto';
import * as http from 'node:http';
import { Readable } from 'node:stream';
type BSQuestionOptions = {
muteAnswer?: boolean;
muteChar?: string;
};
type EncryptedSecret = {
isBuffer: boolean;
iv: string;
authTag: string;
cipherText: string;
};
declare enum LogLevel {
COMPLETE_SILENCE = 0,// Nothing - not even fatals
QUIET = 100,// Log nothing except fatals, errors and warnings
INFO = 200,// Log info messages
START_UP = 250,// Log start up (and shutdown) as well as info messages
DEBUG = 300,// Log debug messages
TRACE = 400
}
declare class Logger {
private _name;
private _timestamp;
private _timestampLocale;
private _timestampTz;
private _logLevel;
private _formatter;
/**
* Generates a timestamp string to prefix log messages.
* Returns an empty string if timestamps are disabled. Otherwise returns
* the formatted timestamp string.
*/
private timestamp;
private convertLevel;
constructor(name: string);
fatal(...args: any): void;
error(...args: any): void;
warn(...args: any): void;
info(...args: any): void;
startupMsg(...args: any): void;
shutdownMsg(...args: any): void;
debug(...args: any): void;
trace(...args: any): void;
force(...args: any): void;
setLevel(level: LogLevel): void;
}
/**
* Config manager module. Provides functions to retrieve config values from various sources like
* CLI, environment variables, and env file. Includes utility functions to handle config value
* lookup, type conversion, error handling etc.
*/
/**
* Type defines the options for retrieving a configuration value.
*
* @param cmdLineFlag - An optional command line flag.
* @param silent - An optional flag to silence logging the retrieval.
* @param redact - An optional flag to redact the value in logs.
*/
type ConfigOptions = {
cmdLineFlag?: string;
silent?: boolean;
redact?: boolean;
};
/**
* Represents an error that occurred while retrieving a config value
*/
declare class ConfigError {
message: string;
constructor(message: string);
}
type ReqRes = {
statusCode: number;
headers: Headers;
body: any;
responseTime: number;
response?: Response;
};
type ReqOptions = {
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS";
searchParams?: Record<string, string>;
headers?: Record<string, string>;
body?: object | [] | string;
auth?: {
username: string;
password: string;
};
bearerToken?: string;
timeoutS?: number;
handleResponse?: boolean;
retries?: number;
baseDelayMs?: number;
keepalive?: boolean;
cache?: RequestCache;
credentials?: RequestCredentials;
mode?: RequestMode;
redirect?: RequestRedirect;
referrer?: string;
referrerPolicy?: ReferrerPolicy;
signal?: AbortSignal;
};
declare class ReqAborted {
timedOut: boolean;
message: string;
constructor(timedOut: boolean, message: string);
}
declare class ReqError {
status: number;
message: string;
constructor(status: number, message: string);
}
type SseServerOptions = {
retryInterval?: number;
pingInterval?: number;
pingEventName?: string;
};
declare class SseServer {
private _res;
private _lastEventId?;
private _pingSeqNum;
constructor(req: http.IncomingMessage, res: http.ServerResponse, opts: SseServerOptions);
get lastEventId(): string | undefined;
setRetry(delay: number): void;
sendData(data: object | unknown[] | string | number, options: {
event?: string;
id?: number;
}): void;
close(): void;
}
type Cookie = {
name: string;
value: string;
maxAge?: number;
path?: string;
secure?: boolean;
httpOnly?: boolean;
sameSite?: "Strict" | "Lax" | "None";
domain?: string;
};
declare class HttpError {
status: number;
message: string;
constructor(status: number, message?: string);
}
type HttpRedirectStatusCode = 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308;
declare class HttpRedirect {
statusCode: HttpRedirectStatusCode;
location: string;
message: string;
constructor(statusCode: HttpRedirectStatusCode | undefined, location: string, message?: string);
}
type ServerTimingMetric = {
name: string;
duration?: number;
description?: string;
};
type ServerRequest = http.IncomingMessage & {
validUrl: boolean;
urlObj: URL;
params: Record<string, any>;
sseServer?: SseServer;
json?: any;
body?: Buffer;
matchedInfo: any;
handled: boolean;
compressResponse: boolean;
checkApiRoutes: boolean;
checkSsrRoutes: boolean;
checkStaticFiles: boolean;
handle404: boolean;
getCookie(cookieName: string): string | null;
setServerTimingHeader(value: string): void;
getBearerToken(): string | null;
};
declare const enhanceIncomingMessage: (req: http.IncomingMessage) => ServerRequest;
type ServerResponse = http.ServerResponse & {
receiveTime: number;
redirected: boolean;
latencyMetricName: string;
serverTimingsMetrics: (ServerTimingMetric | string)[];
body?: string | Buffer;
json?: object | [] | string | number | boolean;
streamRes?: {
body: Readable;
fileName?: string;
};
enhancedReq: ServerRequest;
setCookies(cookies: Cookie[]): void;
clearCookies(cookies: string[], domain?: string): void;
setServerTimingHeader(): void;
redirect(location: string, statusCode?: HttpRedirectStatusCode, message?: string): void;
addServerTimingMetric(name: string, duration?: number, description?: string): void;
addServerTimingHeader(header: string): void;
};
declare const enhanceServerResponse: (res: http.ServerResponse) => ServerResponse;
declare class WebRequest extends Request {
req: ServerRequest;
res: ServerResponse;
constructor(req: ServerRequest, res: ServerResponse);
}
type Middleware = (req: ServerRequest, res: ServerResponse, next: () => Promise<void>) => Promise<void>;
type ExpressMiddleware = (req: http.IncomingMessage, res: http.ServerResponse, next: (e?: any) => void) => void;
type MiddlewareMethods = "GET" | "PUT" | "POST" | "DELETE" | "PATCH";
type CorsOptions = {
originsAllowed?: "*" | string[];
methodsAllowed?: "*" | MiddlewareMethods[];
headersAllowed?: "*" | string[];
headersExposed?: "*" | string[];
credentialsAllowed?: boolean;
maxAge?: number;
};
type CsrfChecksOptions = {
methods?: MiddlewareMethods[];
checkType?: "custom-req-header" | "naive-double-submit-cookie" | "signed-double-submit-cookie";
header?: string;
cookie?: string;
secret?: string;
hashAlgo?: string;
signatureSeparator?: string;
};
type SecurityHeadersOptions = {
headers?: {
name: string;
value: string;
}[];
useDefaultHeaders?: boolean;
};
type StaticFileServerConfig = {
path: string;
immutableRegExp?: string[];
defaultDirFile?: string;
defaultCharSet?: string;
stripHtmlExt?: boolean;
secHeaderOptons?: SecurityHeadersOptions;
cspHeader?: {
inlineScriptHashes: boolean;
directives?: Record<string, string | null>;
};
};
type RouterMatch = {
params: Record<string, string>;
matchedInfo: any;
};
type RouterMatchFunc = (url: URL) => RouterMatch | false;
type SsrRenderFunc = (webReq: WebRequest) => Promise<Response>;
type EndpointOptions = {
generateMatcher?: (path: string) => RouterMatchFunc;
useDefaultMiddlewares?: boolean;
middlewareList?: Middleware[];
sseServerOptions?: SseServerOptions;
etag?: boolean;
};
type EndpointCallback = (req: ServerRequest, res: ServerResponse) => Promise<void> | void;
type Method = "ALL" | "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS" | "HEAD";
type Route = {
get: (callback: EndpointCallback, endpointOptions?: EndpointOptions) => Route;
patch: (callback: EndpointCallback, endpointOptions?: EndpointOptions) => Route;
post: (callback: EndpointCallback, endpointOptions?: EndpointOptions) => Route;
put: (callback: EndpointCallback, endpointOptions?: EndpointOptions) => Route;
del: (callback: EndpointCallback, endpointOptions?: EndpointOptions) => Route;
all: (callback: EndpointCallback, endpointOptions?: EndpointOptions) => Route;
};
type RouterConfig = {
minCompressionSize?: number;
defaultCharSet?: string;
};
declare class Router {
private _httpServerBasePath;
private _routerBasePath;
private _minCompressionSize;
private _defaultCharSet;
private _logger;
private _methodListMap;
private _defaultMiddlewareList;
constructor(httpServerBasePath: string, routerBasePath: string, config?: RouterConfig);
get routerBasePath(): string;
get fullBasePath(): string;
private searchMethodElements;
private findEndpoint;
private callMiddleware;
private callEndpoint;
private hasNoBody;
private bodyNotModified;
private lookupType;
private streamRes;
private addResponseBody;
handleReq(req: ServerRequest, res: ServerResponse): Promise<void>;
static pathToRegexMatcher(path: string): RouterMatchFunc;
static matchAllMatcher(_: string): RouterMatchFunc;
use(middleware: Middleware): Router;
getSsrEndpoint(render: SsrRenderFunc): EndpointCallback;
endpoint(method: Method, path: string, callback: EndpointCallback, endpointOptions?: EndpointOptions): Router;
del(path: string, callback: EndpointCallback, endpointOptions?: EndpointOptions): Router;
get(path: string, callback: EndpointCallback, endpointOptions?: EndpointOptions): Router;
patch(path: string, callback: EndpointCallback, endpointOptions?: EndpointOptions): Router;
post(path: string, callback: EndpointCallback, endpointOptions?: EndpointOptions): Router;
put(path: string, callback: EndpointCallback, endpointOptions?: EndpointOptions): Router;
all(path: string, callback: EndpointCallback, endpointOptions?: EndpointOptions): Router;
route(path: string): Route;
static body(options?: {
maxBodySize?: number;
}): Middleware;
static json(): Middleware;
static cors(options?: CorsOptions): Middleware;
static csrf(options?: CsrfChecksOptions): Middleware;
static secHeaders(options: SecurityHeadersOptions): Middleware;
static expressWrapper(options: ExpressMiddleware): Middleware;
static dontCompressResponse(): Middleware;
static setLatencyMetricName(name: string): Middleware;
static injectReqHeaders(headers: {
name: string;
value: string;
}[]): Middleware;
}
type HealthcheckCallback = () => Promise<boolean>;
declare class HttpConfigError {
message: string;
constructor(message: string);
}
type HttpConfig = {
networkInterface?: string;
networkPort?: number;
keepAliveTimeout?: number;
headerTimeout?: number;
basePath?: string;
defaultRouterBasePath?: string;
healthcheckPath?: string;
enableHttps?: boolean;
httpsKeyFile?: string;
httpsCertFile?: string;
staticFileServer?: StaticFileServerConfig;
ssrServer?: {
adapterName: string;
matcher?: (url: string) => RouterMatchFunc;
render?: SsrRenderFunc;
secHeaderOptons?: SecurityHeadersOptions;
reqHeaders?: {
name: string;
value: string;
}[];
};
};
declare class HttpServer {
private _logger;
private _socketMap;
private _socketId;
private _networkInterface;
private _networkPort;
private _networkIp;
private _listeningOn;
private _name;
private _healthcheckCallbacks;
private _httpKeepAliveTimeout;
private _httpHeaderTimeout;
private _basePath;
private _healthCheckPath;
private _healthCheckGoodResCode;
private _healthCheckBadResCode;
private _enableHttps;
private _keyFile?;
private _certFile?;
private _apiRouterList;
private _defaultApiRouter;
private _ssrRouter;
private _staticFileServer?;
private _server?;
constructor(config: HttpConfig);
get networkIp(): string | null;
get networkPort(): number | null;
get httpsEnabled(): boolean;
get name(): string;
get basePath(): string;
get server(): http.Server | null;
get ssrRouter(): Router | null;
get reqHandler(): (req: ServerRequest, res: ServerResponse) => Promise<void>;
set healthCheckGoodResCode(code: number);
set healthCheckBadResCode(code: number);
private findInterfaceIp;
private startListening;
private handleReq;
private healthcheckCallback;
start(): Promise<void>;
stop(): Promise<void>;
addHealthcheck(callback: HealthcheckCallback): void;
addRouter(basePath: string, routerConfig?: RouterConfig): Router;
router(basePath?: string): Router | undefined;
use(middleware: Middleware): Router;
del(path: string, callback: EndpointCallback, options?: EndpointOptions): Router;
get(path: string, callback: EndpointCallback, options?: EndpointOptions): Router;
patch(path: string, callback: EndpointCallback, options?: EndpointOptions): Router;
post(path: string, callback: EndpointCallback, options?: EndpointOptions): Router;
put(path: string, callback: EndpointCallback, options?: EndpointOptions): Router;
endpoint(method: Method, path: string, callback: EndpointCallback, options?: EndpointOptions): Router;
route(path: string): Route;
}
declare class BSPlugin {
private _name;
private _version;
private _logger;
constructor(name: string, version: string);
protected stop(): Promise<void>;
get name(): string;
get version(): string;
get stopHandler(): () => Promise<void>;
protected fatal(...args: any): void;
protected error(...args: any): void;
protected warn(...args: any): void;
protected info(...args: any): void;
protected startupMsg(...args: any): void;
protected shutdownMsg(...args: any): void;
protected debug(...args: any): void;
protected trace(...args: any): void;
protected force(...args: any): void;
}
declare const bs: Readonly<{
request: (origin: string, path: string, reqOptions?: ReqOptions) => Promise<ReqRes>;
/**
* Gets a string config value.
*
* @param config - The config key to get.
* @param defaultVal - The default value if config not found.
* @param options - Options for getting the config.
* @returns The string config value.
*/
getConfigStr: (config: string, defaultVal?: string, options?: ConfigOptions) => string;
/**
* Gets a boolean config value.
*
* @param config - The config key to get.
* @param defaultVal - The default value if config not found.
* @param options - Options for getting the config.
* @returns The boolean config value.
*/
getConfigBool: (config: string, defaultVal?: boolean, options?: ConfigOptions) => boolean;
/**
* Gets a number config value.
*
* @param config - The config key to get.
* @param defaultVal - The default value if config not found.
* @param options - Options for getting the config.
* @returns The number config value.
*/
getConfigNum: (config: string, defaultVal?: number, options?: ConfigOptions) => number;
/**
* Gets an object config value.
*
* @param config - The config key to get.
* @param defaultVal - The default value if config not found.
* @param options - Options for getting the config.
* @returns The object config value.
*/
getConfigObj: (config: string, defaultVal?: Record<string, any>, options?: ConfigOptions) => Record<string, any>;
/**
* Gets an array config value.
*
* @param config - The config key to get.
* @param defaultVal - The default value if config not found.
* @param options - Options for getting the config.
* @returns The object config value.
*/
getConfigArray: (config: string, defaultVal?: any[], options?: ConfigOptions) => any[];
fatal: (...args: any) => void;
error: (...args: any) => void;
warn: (...args: any) => void;
info: (...args: any) => void;
startupMsg: (...args: any) => void;
shutdownMsg: (...args: any) => void;
debug: (...args: any) => void;
trace: (...args: any) => void;
force: (...args: any) => void;
setLogLevel: (level: LogLevel) => void;
shellVersion: () => string;
setFinallyHandler: (handler: () => Promise<void>) => void;
setStopHandler: (handler: () => Promise<void>) => void;
setRestartHandler: (handler: () => Promise<void>) => void;
exit: (code: number, hard?: boolean) => Promise<void>;
restart: () => Promise<void>;
shutdownError: (code?: number, testing?: boolean) => Promise<void>;
addHttpServer: (httpConfig?: HttpConfig, startServer?: boolean) => Promise<HttpServer>;
httpServer: (index?: number) => HttpServer;
httpServerReady: (index?: number) => boolean;
addPlugin: (name: string, pluginClass: new (name: string, options?: any) => BSPlugin, config?: any) => BSPlugin;
plugin: (name: string) => BSPlugin;
save: (name: string, value: any) => void;
update: (name: string, value: any) => void;
retrieve: (name: string) => any;
sleep: (durationInSeconds: number) => Promise<void>;
question: (ask: string, questionOptions?: BSQuestionOptions) => Promise<string>;
encryptSecret: (secret: string | Buffer, key: string | Buffer, outputEncoding?: crypto.Encoding, inputEncoding?: crypto.Encoding) => EncryptedSecret | null;
decryptSecret: (secret: EncryptedSecret, key: string | Buffer, inputEncoding?: crypto.Encoding, outputEncoding?: crypto.Encoding) => string | Buffer | null;
}>;
export { BSPlugin, ConfigError, HttpConfigError, HttpError, HttpRedirect, HttpServer, LogLevel, Logger, ReqAborted, ReqError, Router, SseServer, WebRequest, bs, enhanceIncomingMessage, enhanceServerResponse };
export type { BSQuestionOptions, ConfigOptions, Cookie, CorsOptions, CsrfChecksOptions, EncryptedSecret, EndpointCallback, EndpointOptions, ExpressMiddleware, HealthcheckCallback, HttpConfig, Middleware, ReqOptions, ReqRes, RouterMatch, RouterMatchFunc, SecurityHeadersOptions, ServerRequest, ServerResponse, SseServerOptions, SsrRenderFunc };