UNPKG

@interopio/gateway

Version:

[![npm version](https://img.shields.io/npm/v/@interopio/gateway.svg)](https://www.npmjs.com/package/@interopio/gateway)

288 lines (240 loc) 8.84 kB
import {Metrics as IOGatewayMetrics} from './types/metrics/api'; import * as IOGatewayAuth from './types/auth/api'; import {RestPublisherConfig} from './types/metrics/publisher/rest'; import {FilePublisherConfig} from './types/metrics/publisher/file'; export default IOGateway.Factory; export declare namespace IOGateway { export const Factory: (options: GatewayConfig) => Gateway; export type AuthenticatorConfig = { timeout?: number } export type BasicAuthenticatorConfig = AuthenticatorConfig & { secretVerifier?: (username?: string, password?: string) => Promise<boolean> }; export type Oauth2AuthenticatorConfig = AuthenticatorConfig & { /** * Base url, used to find the authorization server's app metadata. */ issuerBaseURL?: string /** * Expected JWT "aud" claim value. */ audience?: string } export import Auth = IOGatewayAuth; export type CustomAuthenticator = AuthenticatorConfig & { authenticator: Auth.Authenticator } export type AuthenticationConfig = { /** * Default authentication provider if not specified by the client. */ default?: string /** * List of authentication providers to be used by the gateway */ available?: Exclude<string, 'default' | 'available'>[] basic?: BasicAuthenticatorConfig oauth2?: Oauth2AuthenticatorConfig } | Partial<Record<Exclude<string, 'default' |'available' | 'basic' | 'oauth2'>, CustomAuthenticator>> export type BasicMetricsPublisherConfig = { filters?: MetricFilters, heartbeats?: number buffer_size?: number conflation?: { 'interval'?: number // default 1000 'max-size'?: number // default 0 'max-datapoints-repo'?: number } } export type FileMetricsPublisherConfig = BasicMetricsPublisherConfig & FilePublisherConfig; export type RestMetricsPublisherConfig = BasicMetricsPublisherConfig & RestPublisherConfig; export import Metrics = IOGatewayMetrics; export type CustomMetricsPublisherConfig = BasicMetricsPublisherConfig & { split_size?: number, publisher: { file: string, configuration: unknown; } context?: { gw?: { url: string } [key: string]: unknown } } export type MetricFilters = { publishers: { identity: Record<string, Filtering.Matcher> metrics: { allow?: Filtering.Matcher[] block?: Filtering.Matcher[] /** * @deprecated * @see allow */ whitelist?: Filtering.Matcher[] /** * @deprecated * @see block */ blacklist?: Filtering.Matcher[] } }[], non_matched?: Filtering.Action } export interface MetricPublishersConfig { file: FileMetricsPublisherConfig rest: RestMetricsPublisherConfig } export type MetricsConfig = { publishers: (keyof MetricPublishersConfig | CustomMetricsPublisherConfig)[] filters?: MetricFilters } & Partial<MetricPublishersConfig> export type MeshMember = Readonly<{endpoint: string, node: string }>; export type StaticMeshDirectoryConfig = {members: MeshMember[]}; export type RestMeshDirectoryConfig = {uri?: string, interval?: number}; /** * Gateway Mesh Configuration */ export type MeshConfig = { /** * Node id to be used for mesh. If not specified fallbacks to GatewayConfig#node. */ node?: string /** * @ignore */ broker?: { endpoint: string }, /** * */ cluster?: { endpoint: string, relays?: string directory?: StaticMeshDirectoryConfig | RestMeshDirectoryConfig } } export type VisibilityRule<K extends string> = { identity?: Record<string, Filtering.Matcher> restrictions: 'local' | 'cluster' } & (Partial<Record<K, Filtering.Matcher>>) export type GatewayConfig = { token?: { ttl?: number key?: string }, authentication?: AuthenticationConfig metrics?: MetricsConfig node?: string, contexts?: { /** * Default context lifetime. * @experimental * @default 'ref-counted' */ lifetime?: 'ref-counted' | 'ownership' | 'retained', /** * Default context visibility rules. */ visibility?: VisibilityRule<'context'>[] }, methods?: { /** * Default method visibility rules. */ visibility?: VisibilityRule<'method'>[] }, peers?: { /** * Default peer visibility. */ visibility?: VisibilityRule<'domain'>[] } clients?: { inactive_seconds?: number, buffer_size?: number }, /** * Mesh Configuration. */ mesh?: MeshConfig globals?: { websocket?: typeof WebSocket fetch?: typeof fetch // crypto?: typeof crypto } } export interface Message<T = string> { type: T } export type GatewayClientOptions<T> = { key?: string, codec?: Encoding.Codec<Message, T> onAuthenticate?: (this: GatewayClient<T>, request: Auth.AuthenticationRequest) => Promise<Auth.AuthenticationSuccess> onPing?: (this: GatewayClient<T>) => void onDisconnect?: (this: GatewayClient<T>, reason: 'inactive' | 'shutdown') => void }; export interface Gateway { start(environment?: { endpoint?: string }): Promise<Gateway> stop(): Promise<Gateway> info(): Record<string, unknown> client<T = Message>(handler: (this: GatewayClient<T>, msg: T) => void, opts?: GatewayClientOptions<T>): GatewayClient<T> connect(handler: (client: GatewayClient, msg: Message) => void): Promise<GatewayClient> } export interface GatewayClient<T = Message> { send(msg: T): void close(): void } export namespace Filtering { export type ExactMatch = Omit<string, `#${string}` | `/${string}/`>; export type RegexMatch = RegExp | `#${string}` | `/${string}/`; export type Matcher = ExactMatch | RegExp; export type Action = 'allow' | 'block' // cultural sensitive deprecated values | 'whitelist' | 'blacklist'; export function regexify(expression: ExactMatch | RegexMatch): Matcher; export function valueMatches(expression: Matcher, value?: unknown): boolean; export function valuesMatch(expressions: Matcher[], value?: string): boolean; } export namespace Logging { export interface Logger { trace(message?: string, ...args: unknown[]): void debug(message?: string, ...args: unknown[]): void info(message?: string, ...args: unknown[]): void warn(message?: string, ...args: unknown[]): void error(message?: string, ...args: unknown[]): void enabledFor(level: LogLevel): boolean; } export type LogLevel = Exclude<keyof Logger, 'enabledFor'> export type LogEvent = { time: Date, level: LogLevel, name: string, message: string, data: unknown[] } export type LogConfig = { level: LogLevel | { [key: string]: LogLevel } appender?: (event: LogEvent) => void } export function configure(config: LogConfig): void; export function getLogger(name: string): Logger; } export namespace Encoding { export type Codec<T, R> = { encode: (msg: T) => R; decode: (data: R) => T; }; export type KeywordizeCommand = '*' // keywordize for all string values for ex {:type :cluster} | Set<string> // keywordize only specific values | null // stop keywordization (even for keys) ; export function transit<T>(opts?: { keywordize?: Map<string, KeywordizeCommand>; verbose?: boolean; namespaces?: Map<string, string>; }): Codec<T, string>; export function json<T>(): Codec<T, string>; export function direct<T>(opts?: { cljs?: boolean }): Codec<T, T>; } }