@interopio/gateway
Version:
[](https://www.npmjs.com/package/@interopio/gateway)
288 lines (240 loc) • 8.84 kB
TypeScript
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>;
}
}