zod-sockets
Version:
Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers
702 lines (680 loc) • 27.4 kB
TypeScript
import http, { IncomingMessage } from 'node:http';
import { RemoteSocket, Socket, Server } from 'socket.io';
import { z } from 'zod/v4';
import ts from 'typescript';
interface FlowCommons {
/** @desc The URL to be used for obtaining refresh tokens. */
refreshUrl?: string;
/** @desc A map between the scope name and a short description for it. */
availableScopes: Record<string, string>;
}
interface AuthHavingFlow {
/** @desc The authorization URL to be used for this flow. */
authorizationUrl: string;
}
interface TokenHavingFlow {
/** @desc The token URL to be used for this flow. */
tokenUrl: string;
}
interface OAuthFlowsObject {
implicit?: FlowCommons & AuthHavingFlow;
password?: FlowCommons & TokenHavingFlow;
clientCredentials?: FlowCommons & TokenHavingFlow;
authorizationCode?: FlowCommons & AuthHavingFlow & TokenHavingFlow;
}
interface HttpApiKeySecurity {
type: "httpApiKey";
/** @desc The name of the header, query or cookie parameter to be used. */
name: string;
in: "query" | "header" | "cookie";
}
interface ApiKeySecurity {
type: "apiKey";
in: "user" | "password";
}
interface HttpSecurity {
type: "http";
/** @link https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml */
scheme?: string;
/** @example "Bearer" */
bearerFormat?: string;
}
interface ScopesHavingSecurity {
/** @desc List of the needed scope names. An empty array means no scopes are needed. */
scopes?: string[];
}
interface OAuth2Security extends ScopesHavingSecurity {
type: "oauth2";
flows: OAuthFlowsObject;
}
interface OpenIdConnectSecurity extends ScopesHavingSecurity {
type: "openIdConnect";
/** @desc OpenId Connect URL to discover OAuth2 configuration values */
openIdConnectUrl: string;
}
interface OtherSecurity {
type: "userPassword" | "X509" | "symmetricEncryption" | "asymmetricEncryption" | "plain" | "scramSha256" | "scramSha512" | "gssapi";
}
type SecuritySchemeObject = {
description?: string;
} & (HttpApiKeySecurity | ApiKeySecurity | HttpSecurity | OAuth2Security | OpenIdConnectSecurity | OtherSecurity);
type EmptyObject = Record<string, never>;
interface Distribution {
join: (rooms: string | string[]) => Promise<void>;
leave: (rooms: string | string[]) => Promise<void>;
}
type SomeRemoteSocket = RemoteSocket<Record<string, (...args: any[]) => void>, unknown>;
interface RemoteClient<E extends EmissionMap, D extends z.ZodObject> extends Distribution {
id: string;
handshake: SomeRemoteSocket["handshake"];
rooms: string[];
getData: () => Readonly<Partial<z.infer<D>>>;
emit: Emitter<E>;
}
interface Emission {
schema: z.ZodTuple;
ack?: z.ZodTuple;
}
type EmissionMap = Record<string, Emission>;
type TupleOrTrue<T> = T extends z.ZodTuple ? T : z.ZodLiteral<true>;
type TuplesOrTrue<T> = T extends z.ZodTuple ? z.ZodArray<T> : z.ZodLiteral<true>;
type Emitter<E extends EmissionMap> = <K extends keyof E>(evt: K, ...args: z.input<E[K]["schema"]>) => Promise<z.output<TupleOrTrue<E[K]["ack"]>>>;
type Broadcaster<E extends EmissionMap> = <K extends keyof E>(evt: K, ...args: z.input<E[K]["schema"]>) => Promise<z.output<TuplesOrTrue<E[K]["ack"]>>>;
type RoomService<E extends EmissionMap, D extends z.ZodObject> = (rooms: string | string[]) => {
/**
* @desc Emits an event to all/others (depending on context) in the specified room(s)
* @throws z.ZodError on validation
* @throws Error on ack timeout
* */
broadcast: Broadcaster<E>;
getClients: () => Promise<RemoteClient<E, D>[]>;
};
interface Client<E extends EmissionMap, D extends z.ZodObject> extends Distribution {
/** @alias Socket.connected */
isConnected: () => boolean;
/** @alias Socket.id */
id: Socket["id"];
handshake: Socket["handshake"];
/**
* @desc When using express-session:
* @example getRequest<express.Request>().session
**/
getRequest: <T extends IncomingMessage = Socket["request"]>() => T;
/** @desc Returns the list of the rooms the client in */
getRooms: () => string[];
/**
* @desc Sends a new event to the client (this is not acknowledgement)
* @throws z.ZodError on validation
* @throws Error on ack timeout
* */
emit: Emitter<E>;
/**
* @desc Emits to others
* @throws z.ZodError on validation
* @throws Error on ack timeout
* */
broadcast: Broadcaster<E>;
/** @desc Returns the client metadata according to the specified type or empty object */
getData: () => Readonly<Partial<z.infer<D>>>;
/**
* @desc Sets the client metadata according to the specified type
* @throws z.ZodError on validation
* */
setData: (value: z.infer<D>) => void;
}
/**
* @desc Using module augmentation approach you can set the type of the actual logger used
* @example declare module "zod-sockets" { interface LoggerOverrides extends winston.Logger {} }
* @link https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
* */
interface LoggerOverrides {
}
/** @desc You can use any logger compatible with this type. */
type AbstractLogger = Record<"info" | "debug" | "warn" | "error", (message: string, meta?: any) => any> & LoggerOverrides;
interface IndependentContext<E extends EmissionMap, D extends z.ZodObject> {
logger: AbstractLogger;
all: {
/** @desc Returns the list of available rooms */
getRooms: () => string[];
/** @desc Returns the list of familiar clients */
getClients: () => Promise<RemoteClient<E, D>[]>;
/** @desc Emits an event to everyone */
broadcast: Broadcaster<E>;
};
/** @desc Provides room(s)-scope methods */
withRooms: RoomService<E, D>;
}
interface ClientContext<E extends EmissionMap, D extends z.ZodObject> extends IndependentContext<E, D> {
/** @desc The sender of the incoming event */
client: Client<E, D>;
}
interface TracingContext<E extends EmissionMap, D extends z.ZodObject> extends ClientContext<E, D> {
event: string;
payload: unknown[];
}
interface ErrorContext<E extends EmissionMap, D extends z.ZodObject> extends IndependentContext<E, D>, Partial<Pick<TracingContext<E, D>, "event" | "payload" | "client">> {
error: Error;
}
interface ActionContext<IN, E extends EmissionMap, D extends z.ZodObject> extends ClientContext<E, D> {
/** @desc Validated payload */
input: IN;
}
type Handler<CTX, OUT> = (params: CTX) => Promise<OUT>;
interface Hooks<E extends EmissionMap, D extends z.ZodObject> {
/** @desc The place for emitting events regardless receiving events */
onConnection: Handler<ClientContext<E, D>, void>;
onDisconnect: Handler<ClientContext<E, D>, void>;
onAnyIncoming: Handler<TracingContext<E, D>, void>;
onAnyOutgoing: Handler<TracingContext<E, D>, void>;
/** @desc The place for emitting events regardless clients activity */
onStartup: Handler<IndependentContext<E, D>, void>;
/** @desc The place for handling errors, in particular validation errors of the incoming events */
onError: Handler<ErrorContext<E, D>, void>;
}
declare const rootNS = "/";
type RootNS = typeof rootNS;
interface Namespace<E extends EmissionMap, D extends z.ZodObject> {
/** @desc The events that the server can emit */
emission: E;
/** @desc Handlers for some events in different contexts */
hooks: Partial<Hooks<E, D>>;
/** @desc Schema of the client metadata in this namespace */
metadata: D;
security: SecuritySchemeObject[];
}
type Namespaces = Record<string, Namespace<EmissionMap, z.ZodObject>>;
interface ConstructorOptions<NS extends Namespaces> {
/**
* @desc The acknowledgment awaiting timeout
* @default 2000
* */
timeout?: number;
/**
* @desc You can disable the startup logo.
* @default true
*/
startupLogo?: boolean;
/**
* @desc Define namespaces inline or consider using addNamespace() method
* @default {}
* @see Namespace
* */
namespaces?: NS;
security?: SecuritySchemeObject[];
}
/** @todo consider using it for namespaces declaration only */
declare class Config<T extends Namespaces = EmptyObject> {
constructor({ timeout, startupLogo, namespaces, security, }?: ConstructorOptions<T>);
/** @default { path: "/", emission: {}, metadata: z.object({}), hooks: {}, examples: {}, security: [] } */
addNamespace<E extends EmissionMap = EmptyObject, D extends z.ZodObject = z.ZodObject<EmptyObject>, K extends string = RootNS>({ path, emission, metadata, hooks, security, }: Partial<Namespace<E, D>> & {
path?: K;
}): Config<Omit<T, K> & Record<K, Namespace<E, D>>>;
}
/** @desc Shorthand for single namespace config (root namespace only) */
declare const createSimpleConfig: <E extends EmissionMap, D extends z.ZodObject>({ startupLogo, timeout, security, emission, hooks, metadata, }?: Omit<ConstructorOptions<never>, "namespaces"> & Partial<Namespace<E, D>>) => Config<Omit<EmptyObject, "/"> & Record<"/", Namespace<E, D>>>;
interface Commons<IN extends z.ZodTuple, NS extends Namespaces, K extends keyof NS> {
/** @desc The incoming event payload validation schema (without or excluding acknowledgement) */
input: IN;
/**
* @desc The namespace this Action belongs to (optional)
* @default "/"
* */
ns?: K;
/** @desc The incoming event name */
event: string;
}
interface ActionNoAckDef<IN extends z.ZodTuple, NS extends Namespaces, K extends keyof NS> extends Commons<IN, NS, K> {
/** @desc No output schema => no returns => no acknowledgement */
handler: Handler<ActionContext<z.output<IN>, NS[K]["emission"], NS[K]["metadata"]>, void>;
}
interface ActionWithAckDef<IN extends z.ZodTuple, OUT extends z.ZodTuple, NS extends Namespaces, K extends keyof NS> extends Commons<IN, NS, K> {
/** @desc The acknowledgement validation schema */
output: OUT;
/** @desc The returns become an Acknowledgement */
handler: Handler<ActionContext<z.output<IN>, NS[K]["emission"], NS[K]["metadata"]>, z.input<OUT>>;
}
declare class ActionsFactory<NS extends Namespaces> {
protected config: Config<NS>;
constructor(config: Config<NS>);
build<IN extends z.ZodTuple, OUT extends z.ZodTuple | undefined = undefined, K extends keyof NS = RootNS>(def: ActionNoAckDef<IN, NS, K> | ActionWithAckDef<IN, NonNullable<OUT>, NS, K>): Action<NS, IN, OUT>;
}
declare abstract class AbstractAction {
abstract execute(params: {
params: unknown[];
} & ClientContext<EmissionMap, z.ZodObject>): Promise<void>;
}
declare class Action<NS extends Namespaces, IN extends z.ZodTuple, OUT extends z.ZodTuple | undefined = undefined> extends AbstractAction {
#private;
constructor(action: ActionWithAckDef<IN, NonNullable<OUT>, NS, keyof NS> | ActionNoAckDef<IN, NS, keyof NS>);
get event(): string;
get namespace(): keyof NS;
get inputSchema(): IN;
get outputSchema(): OUT;
execute({ params, logger, ...rest }: {
params: unknown[];
} & ClientContext<EmissionMap, z.ZodObject>): Promise<void>;
}
declare const attachSockets: <NS extends Namespaces>({ io, actions, target, config: { namespaces, timeout, startupLogo }, logger: rootLogger, }: {
/**
* @desc The Socket.IO server
* @example new Server()
* */
io: Server;
/**
* @desc The array of handling rules for the incoming Socket.IO events
* @example [ onPing ]
* */
actions: AbstractAction[];
/**
* @desc HTTP or HTTPS server to attach the sockets to
* @example http.createServer().listen(8090)
* */
target: http.Server;
/** @desc The configuration describing the emission (outgoing events) */
config: Config<NS>;
/**
* @desc The instance of a logger
* @default console
* */
logger?: AbstractLogger;
}) => Promise<Server>;
interface IntegrationProps {
config: Config<Namespaces>;
actions: AbstractAction[];
/**
* @desc When event has both .rest() and an acknowledgement, the "...rest" can not be placed in a middle.
* @desc In this case, overloads are used to reflect variations on different number of the function arguments.
* @default 3
* @example ( (cb) => void ) | ( (rest1, cb) => void ) | ( (rest1, rest2, cb) => void )
*/
maxOverloads?: number;
}
declare const registryScopes: string[];
declare class Integration {
#private;
protected registry: Record<string, // namespace
Record<(typeof registryScopes)[number], {
event: string;
node: ts.TypeNode;
}[]>>;
constructor({ config: { namespaces }, actions, maxOverloads, }: IntegrationProps);
print(printerOptions?: ts.PrinterOptions): string;
}
/** @see https://github.com/asyncapi/bindings/tree/master/websockets */
declare namespace WS {
/** @desc This object MUST NOT contain any properties. Its name is reserved for future use. */
interface Server {
}
/**
* @desc When using WebSockets, the channel represents the connection. Unlike other protocols that support multiple
* @desc virtual channels (topics, routing keys, etc.) per connection, WebSockets doesn't support virtual channels or,
* @desc put it another way, there's only one channel and its characteristics are strongly related to the protocol
* @desc used for the handshake, i.e., HTTP.
*/
interface Channel {
/**
* @desc The HTTP method to use when establishing the connection. Its value MUST be either GET or POST.
* */
method: "GET" | "POST";
/**
* @desc A Schema object containing the definitions for each query parameter.
* @desc This schema MUST be of type object and have a properties key.
*/
query: SchemaObject | ReferenceObject;
/**
* @desc A Schema object containing the definitions of the HTTP headers to use when establishing the connection.
* @desc This schema MUST be of type object and have a properties key.
*/
headers: SchemaObject | ReferenceObject;
/**
* @desc The version of this binding. If omitted, "latest" MUST be assumed.
*/
bindingVersion: "0.1.0";
}
/**
* @desc This object MUST NOT contain any properties. Its name is reserved for future use.
* */
interface Operation {
}
/** @desc This object MUST NOT contain any properties. Its name is reserved for future use. */
interface Message {
}
}
/**
* @fileoverview AsyncAPI specification
* @version 3.0.0
*/
interface Bindings<T> {
ws?: T;
}
/** @since 3.0.0 detached from OAS; added host, pathname, title, description, tags, externalDocs; changed security */
interface ServerObject {
host: string;
protocol: string;
protocolVersion?: string;
pathname?: string;
title?: string;
description?: string;
variables?: Record<string, ServerVariableObject>;
security?: Array<SecuritySchemeObject | ReferenceObject>;
tags?: TagObject[];
externalDocs?: ExternalDocumentationObject;
bindings?: Bindings<WS.Server>;
}
interface ContactObject {
name?: string;
url?: string;
email?: string;
}
interface LicenseObject {
name: string;
url?: string;
}
/** @since 3.0.0 contains tags and externalDocs */
interface InfoObject {
title: string;
version: string;
description?: string;
termsOfService?: string;
contact?: ContactObject;
license?: LicenseObject;
tags?: TagObject[];
externalDocs?: ExternalDocumentationObject;
}
/** @since 3.0.0 channels are optional, added operations */
interface AsyncApiObject {
asyncapi: string;
/** @desc URI or URN format */
id?: string;
info: InfoObject;
servers?: Record<string, ServerObject>;
channels?: ChannelsObject;
operations?: OperationsObject;
components?: ComponentsObject;
defaultContentType?: string;
}
/**
* @since 3.0.0 An identifier for the described channel. The channelId value is case-sensitive.
* */
type ChannelsObject = Record<string, ChannelObject>;
interface ReferenceObject {
$ref: string;
}
/** @since 3.0.0 renamed; added address, title, summary, messages, servers, tags, externalDocs; removed pubs/subs */
interface ChannelObject {
/** @desc Typically the "topic name", "routing key", "event type", or "path". */
address?: string | null;
title?: string;
summary?: string;
description?: string;
messages?: MessagesObject;
servers?: ReferenceObject[];
/** @desc Describes a map of parameters included in a channel name. */
parameters?: ParametersObject;
tags?: TagObject[];
externalDocs?: ExternalDocumentationObject;
/** @desc Map describing protocol-specific definitions for a channel. */
bindings?: Bindings<WS.Channel>;
}
interface ServerVariableObject {
enum?: string[] | boolean[] | number[];
default: string | boolean | number;
description?: string;
examples?: string[];
}
type SchemaObjectType = "integer" | "number" | "string" | "boolean" | "object" | "null" | "array";
/**
* @desc DRAFT-07
* @link https://json-schema.org/specification-links#draft-7
* @link https://json-schema.org/draft-07/draft-handrews-json-schema-validation-01
* */
interface Draft07 {
title?: string;
type?: SchemaObjectType | SchemaObjectType[];
required?: string[];
multipleOf?: number;
maximum?: number;
exclusiveMaximum?: number;
minimum?: number;
exclusiveMinimum?: number;
maxLength?: number;
minLength?: number;
pattern?: string;
maxItems?: number;
minItems?: number;
uniqueItems?: boolean;
maxProperties?: number;
minProperties?: number;
enum?: any[];
const?: any;
examples?: any[];
readOnly?: boolean;
writeOnly?: boolean;
properties?: {
[propertyName: string]: SchemaObject | ReferenceObject;
};
patternProperties?: {
[pattern: string]: SchemaObject | ReferenceObject;
};
additionalProperties?: SchemaObject | ReferenceObject | boolean;
additionalItems?: SchemaObject | ReferenceObject | boolean;
items?: SchemaObject | ReferenceObject | [
SchemaObject | ReferenceObject,
...Array<SchemaObject | ReferenceObject>
];
propertyNames?: SchemaObject | ReferenceObject;
contains?: SchemaObject;
allOf?: (SchemaObject | ReferenceObject)[];
oneOf?: (SchemaObject | ReferenceObject)[];
anyOf?: (SchemaObject | ReferenceObject)[];
not?: SchemaObject | ReferenceObject;
/**
* @desc JSON Schema compliant Content-Type, optional when specified as a key of ContentObject
* @example image/png
*/
contentMediaType?: string;
/**
* @desc Specifies the Content-Encoding for the schema, supports all encodings from RFC4648, and "quoted-printable" from RFC2045
* @override format
* @see https://datatracker.ietf.org/doc/html/rfc4648
* @see https://datatracker.ietf.org/doc/html/rfc2045#section-6.7
* @example base64
*/
contentEncoding?: string;
}
/** @link https://www.asyncapi.com/docs/reference/specification/v3.0.0#schemaObject */
interface SchemaObject extends Draft07 {
description?: string;
format?: "int32" | "int64" | "float" | "double" | "byte" | "binary" | "date" | "date-time" | "password" | string;
default?: any;
discriminator?: string;
externalDocs?: ExternalDocumentationObject | ReferenceObject;
deprecated?: boolean;
}
/** @since 3.0.0 added replies */
interface ComponentsObject {
schemas?: Record<string, SchemaObject | ReferenceObject>;
servers?: Record<string, ServerObject>;
serverVariables?: Record<string, ServerVariableObject>;
channels?: Record<string, ChannelObject>;
messages?: Record<string, MessageObject>;
securitySchemes?: Record<string, SecuritySchemeObject>;
parameters?: Record<string, ParameterObject>;
correlationIds?: Record<string, CorrelationIDObject>;
operationTraits?: Record<string, OperationTraitObject>;
messageTraits?: Record<string, MessageTraitObject>;
replies?: Record<string, OperationReplyObject>;
serverBindings?: Bindings<WS.Server>;
channelBindings?: Bindings<WS.Channel>;
operationBindings?: Bindings<WS.Operation>;
messageBindings?: Bindings<WS.Message>;
}
/** @since 3.0.0 supports MultiFormatSchemaObject in payload */
interface MessageObject extends MessageTraitObject {
payload?: SchemaObject | MultiFormatSchemaObject | ReferenceObject;
traits?: MessageTraitObject | ReferenceObject;
}
/** @desc The key represents the message identifier. The messageId value is case-sensitive. */
type MessagesObject = Record<string, MessageObject | ReferenceObject>;
/** @since 3.0.0 added action, channel, messages, reply */
interface OperationObject extends OperationTraitObject {
action: "send" | "receive";
/** @desc A $ref pointer to the definition of the channel in which this operation is performed. */
channel: ReferenceObject;
/** @desc A list of $ref pointers pointing to the supported Message Objects that can be processed by this operation */
messages?: ReferenceObject[];
reply?: OperationReplyObject | ReferenceObject;
traits?: Record<string, OperationTraitObject>;
}
/**
* @desc Describes the reply part that MAY be applied to an Operation Object.
* @desc If an operation implements the request/reply pattern, the reply object represents the response message.
* @since 3.0.0 new
* */
interface OperationReplyObject {
/** @desc Definition of the address that implementations MUST use for the reply. */
address?: OperationReplyAddressObject | ReferenceObject;
/** @desc A $ref pointer to the definition of the channel in which this operation is performed. */
channel?: ReferenceObject;
/** @desc A list of pointers to the supported Message Objects that can be processed by this operation as reply */
messages?: ReferenceObject[];
}
/**
* @desc An object that specifies where an operation has to send the reply.
* @since 3.0.0 new
* */
interface OperationReplyAddressObject {
/**
* @desc A runtime expression that specifies the location of the reply address.
* @example $message.header#/replyTo
* @example $message.payload#/messageId
* @link https://www.asyncapi.com/docs/reference/specification/v3.0.0#runtimeExpression
* */
location: string;
description?: string;
}
/**
* @desc The operation this application MUST implement. The field name (operationId) MUST be a string used to
* @desc identify the operation in the document where it is defined, and its value is case-sensitive.
* */
type OperationsObject = Record<string, OperationObject>;
/** @since 3.0.0 operationId moved to OperationsObject; added title, security */
interface OperationTraitObject {
title?: string;
summary?: string;
description?: string;
security?: Array<SecuritySchemeObject | ReferenceObject>;
tags?: TagObject[];
externalDocs?: ExternalDocumentationObject;
bindings?: Bindings<WS.Operation>;
}
/** @since 3.0.0 messageId moved to MessagesObject, schemaFormat moved to MultiFormatSchemaObject */
interface MessageTraitObject {
headers?: SchemaObject | MultiFormatSchemaObject;
correlationId?: CorrelationIDObject;
contentType?: string;
name?: string;
title?: string;
summary?: string;
description?: string;
tags?: TagObject[];
externalDocs?: ExternalDocumentationObject;
bindings?: Bindings<WS.Message>;
examples?: MessageExampleObject[];
}
/**
* @desc Represents an example of a Message Object and MUST contain either headers and/or payload fields.
* @since 3.0.0 new
* */
interface MessageExampleObject {
name?: string;
summary?: string;
headers?: Record<string, any>;
payload?: any;
}
/** @since 3.0.0 new */
interface MultiFormatSchemaObject {
/**
* @desc A string containing the name of the schema format that is used to define the information.
* @example application/vnd.aai.asyncapi+yaml;version=3.0.0
* @example application/schema+yaml;version=draft-07
* @example application/vnd.oai.openapi+yaml;version=3.0.0
* */
schemaFormat: string;
schema: SchemaObject;
}
interface CorrelationIDObject {
description?: string;
/**
* @desc A runtime expression that specifies the location of the correlation ID.
* @example $message.header#/correlationId
* @link https://www.asyncapi.com/docs/reference/specification/v3.0.0#runtimeExpression
* */
location: string;
}
interface TagObject {
name: string;
description?: string;
externalDocs?: ExternalDocumentationObject;
}
/** @since 3.0.0 partially extends SchemaObject; schema prop removed */
interface ParameterObject extends Pick<SchemaObject, "enum" | "default" | "description" | "examples"> {
/**
* @desc A runtime expression that specifies the location of the parameter value.
* @link https://www.asyncapi.com/docs/reference/specification/v3.0.0#runtimeExpression
* */
location?: string;
}
/** @desc Property pattern ^[A-Za-z0-9_\-]+$ */
type ParametersObject = Record<string, ParameterObject>;
interface ExternalDocumentationObject {
description?: string;
url: string;
}
declare class AsyncApiBuilder {
protected readonly document: AsyncApiObject;
constructor(initial: Pick<AsyncApiObject, "info" | "id" | "defaultContentType">);
addServer(name: string, server: ServerObject): this;
addChannel(name: string, channel: ChannelObject): this;
addOperation(name: string, operation: OperationObject): this;
addSecurityScheme(name: string, schema: SecuritySchemeObject): this;
addSchema(name: string, schema: SchemaObject | ReferenceObject): this;
getSpec(): AsyncApiObject;
getSpecAsJson(replacer?: (key: string, value: unknown) => unknown, space?: string | number): string;
getSpecAsYaml(): string;
}
interface DocumentationParams {
title: string;
version: string;
documentId?: string;
description?: string;
contact?: ContactObject;
license?: LicenseObject;
servers?: Record<string, {
url: string;
description?: string;
}>;
actions: AbstractAction[];
config: Config<Namespaces>;
}
declare class Documentation extends AsyncApiBuilder {
#private;
constructor({ actions, config: { namespaces, security: globalSecurity }, title, version, documentId, description, contact, license, servers, }: DocumentationParams);
}
/** @desc An error related to the input and output schemas declaration */
declare class IOSchemaError extends Error {
name: string;
}
/** @desc An error of validating the incoming data */
declare class InputValidationError extends IOSchemaError {
readonly cause: z.ZodError;
name: string;
constructor(cause: z.ZodError);
}
/** @desc An error of validating the outgoing data */
declare class OutputValidationError extends IOSchemaError {
readonly cause: z.ZodError;
name: string;
constructor(cause: z.ZodError);
}
export { AbstractAction, type AbstractLogger, ActionsFactory, type ClientContext, Config, Documentation, type EmissionMap, InputValidationError, Integration, type LoggerOverrides, type Namespace, OutputValidationError, attachSockets, createSimpleConfig };