Skip to content

@amqp-contract/contract


@amqp-contract/contract ​

Type Aliases ​

AnySchema ​

ts
type AnySchema = StandardSchemaV1;

Defined in: types.ts:14

Any schema that conforms to Standard Schema v1.

This library supports any validation library that implements the Standard Schema v1 specification, including Zod, Valibot, and ArkType. This allows you to use your preferred validation library while maintaining type safety.

See ​

https://github.com/standard-schema/standard-schema


BaseExchangeDefinition ​

ts
type BaseExchangeDefinition<TName> = object;

Defined in: types.ts:426

Base definition of an AMQP exchange.

An exchange receives messages from publishers and routes them to queues based on the exchange type and routing rules. This type contains properties common to all exchange types.

Type Parameters ​

Type ParameterDefault type
TName extends stringstring

Properties ​

PropertyTypeDescriptionDefined in
arguments?Record<string, unknown>Additional AMQP arguments for advanced configuration. Common arguments include alternate-exchange for handling unroutable messages.types.ts:453
autoDelete?booleanIf true, the exchange is deleted when all queues have finished using it.types.ts:441
durable?booleanIf true, the exchange survives broker restarts. Durable exchanges are persisted to disk. Default truetypes.ts:436
internal?booleanIf true, the exchange cannot be directly published to by clients. It can only receive messages from other exchanges via exchange-to-exchange bindings.types.ts:447
nameTNameThe name of the exchange. Must be unique within the RabbitMQ virtual host.types.ts:430

BindingDefinition ​

ts
type BindingDefinition = 
  | QueueBindingDefinition
  | ExchangeBindingDefinition;

Defined in: types.ts:905

Union type of all binding definitions.

A binding can be either:

  • Queue-to-exchange binding: Routes messages from an exchange to a queue
  • Exchange-to-exchange binding: Forwards messages from one exchange to another

BindingPattern ​

ts
type BindingPattern<S> = S extends "" ? never : S;

Defined in: builder/routing-types.ts:52

Type-safe binding pattern that validates basic format and wildcards.

Validates that a binding pattern follows basic AMQP binding pattern rules:

  • Can contain wildcards (* for one word, # for zero or more words)
  • Must not be empty
  • Should contain alphanumeric characters, dots, hyphens, underscores, and wildcards

Note: Full character-by-character validation is not performed to avoid TypeScript recursion depth limits. Runtime validation is still recommended.

Type Parameters ​

Type ParameterDescription
S extends stringThe binding pattern string to validate

Example ​

typescript
type ValidPattern = BindingPattern<"order.*">; // "order.*"
type ValidHash = BindingPattern<"order.#">; // "order.#"
type ValidConcrete = BindingPattern<"order.created">; // "order.created"
type Invalid = BindingPattern<"">; // never (empty string)

BoundContract ​

ts
type BoundContract<C, B> = BoundProtocol<Pick<C, keyof C & keyof ContractDefinition>, B>;

Defined in: contract-binding.ts:62

Protocol keys and schemas survive binding; topology maps use physical names.

Type Parameters ​

Type Parameter
C extends ContractDefinition
B extends ContractBinding

BridgedPublisherConfig ​

ts
type BridgedPublisherConfig<TMessage, TBridgeExchange, TTargetExchange> = object;

Defined in: builder/command.ts:65

Configuration for a bridged command publisher.

A bridged publisher publishes to a bridge exchange (local domain), which forwards messages to the target exchange (remote domain) via an exchange-to-exchange binding.

Type Parameters ​

Type ParameterDescription
TMessage extends MessageDefinitionThe message definition
TBridgeExchange extends ExchangeDefinitionThe bridge (local domain) exchange definition
TTargetExchange extends ExchangeDefinitionThe target (remote domain) exchange definition

Properties ​

PropertyModifierTypeDescriptionDefined in
[brand]readonly"BridgedPublisherConfig"Discriminator to identify this as a bridged publisher configbuilder/command.ts:71
bridgeExchangepublicTBridgeExchangeThe bridge (local domain) exchangebuilder/command.ts:77
exchangeBindingpublicExchangeBindingDefinitionThe exchange-to-exchange binding (bridge → target)builder/command.ts:75
publisherpublicPublisherDefinition<TMessage>The publisher definition (publishes to bridge exchange)builder/command.ts:73
targetExchangepublicTTargetExchangeThe target (remote domain) exchangebuilder/command.ts:79

BridgedPublisherConfigBase ​

ts
type BridgedPublisherConfigBase = object;

Defined in: types.ts:1051

Base type for bridged publisher configuration.

A bridged publisher publishes to a bridge exchange, which forwards messages to the target exchange via an exchange-to-exchange binding.

See ​

defineCommandPublisher with bridgeExchange option

Properties ​

PropertyModifierTypeDefined in
[brand]readonly"BridgedPublisherConfig"types.ts:1052
bridgeExchangepublicExchangeDefinitiontypes.ts:1055
exchangeBindingpublicExchangeBindingDefinitiontypes.ts:1054
publisherpublicPublisherDefinitiontypes.ts:1053
targetExchangepublicExchangeDefinitiontypes.ts:1056

ClassicQueueDefinition ​

ts
type ClassicQueueDefinition<TName> = BaseQueueDefinition<TName> & object;

Defined in: types.ts:671

Definition of a classic queue.

Classic queues are the traditional RabbitMQ queue type. Use them when you need specific features not supported by quorum queues (e.g., exclusive queues, auto-deleting queues, x-max-priority priority levels).

Type Parameters ​

Type ParameterDefault type
TName extends stringstring

Type Declaration ​

NameTypeDescriptionDefined in
autoDelete?booleanIf true, the queue is deleted when the last consumer unsubscribes.types.ts:691
durablebooleanIf true, the queue survives broker restarts. Durable queues are persisted to disk.types.ts:680
exclusive?booleanIf true, the queue can only be used by the declaring connection and is deleted when that connection closes. Exclusive queues are private to the connection.types.ts:686
maxPriority?numberMaximum priority level for priority queue (1-255, recommended: 1-10). Sets x-max-priority argument.types.ts:697
type"classic"Queue type discriminator: classic queue.types.ts:675

ClassicQueueOptions ​

ts
type ClassicQueueOptions = BaseQueueOptions & object;

Defined in: types.ts:373

Options for creating a classic queue.

Classic queues support all traditional RabbitMQ features including:

  • exclusive - For connection-scoped queues
  • autoDelete - For auto-deleting queues when consumers disconnect
  • maxPriority - For x-max-priority priority levels
  • durable: false - For non-durable queues

Type Declaration ​

NameTypeDescriptionDefined in
autoDelete?booleanIf true, the queue is deleted when the last consumer unsubscribes.types.ts:394
durable?booleanIf true, the queue survives broker restarts. Durable queues are persisted to disk. Default truetypes.ts:383
exclusive?booleanIf true, the queue can only be used by the declaring connection and is deleted when that connection closes. Exclusive queues are private to the connection.types.ts:389
maxPriority?numberMaximum priority level for priority queue (1-255, recommended: 1-10). Sets x-max-priority argument.types.ts:400
type"classic"Queue type: classic (for special cases)types.ts:377

Example ​

typescript
const priorityQueue = defineQueue('tasks', {
  type: 'classic',
  maxPriority: 10,
});

CommandConsumerConfig ​

ts
type CommandConsumerConfig<TMessage, TExchange, TRoutingKey, TQueue> = object;

Defined in: builder/command.ts:33

Configuration for a command consumer.

Commands are sent by one or more publishers to a single consumer (task queue pattern). The consumer "owns" the queue, and publishers send commands to it.

Type Parameters ​

Type ParameterDefault typeDescription
TMessage extends MessageDefinition-The message definition
TExchange extends ExchangeDefinition-The exchange definition
TRoutingKey extends string | undefinedundefinedThe routing key type (undefined for fanout and headers exchanges)
TQueue extends QueueDefinitionQueueDefinition-

Properties ​

PropertyModifierTypeDescriptionDefined in
[brand]readonly"CommandConsumerConfig"Discriminator to identify this as a command consumer configbuilder/command.ts:40
bindingpublicQueueBindingDefinitionThe binding connecting the queue to the exchangebuilder/command.ts:44
consumerpublicConsumerDefinition<TMessage>The consumer definition for processing commandsbuilder/command.ts:42
exchangepublicTExchangeThe exchange that receives commandsbuilder/command.ts:46
messagepublicTMessageThe message definitionbuilder/command.ts:50
queuepublicTQueueThe queue this consumer reads frombuilder/command.ts:48
routingKeypublicTRoutingKeyThe routing key pattern for the bindingbuilder/command.ts:52

CommandConsumerConfigBase ​

ts
type CommandConsumerConfigBase = object;

Defined in: types.ts:1015

Base type for command consumer configuration.

This is a simplified type used in ContractDefinition. The full generic type is defined in the builder module.

See ​

defineCommandConsumer for creating command consumers

Properties ​

PropertyModifierTypeDefined in
[brand]readonly"CommandConsumerConfig"types.ts:1016
bindingpublicQueueBindingDefinitiontypes.ts:1018
consumerpublicConsumerDefinitiontypes.ts:1017
exchangepublicExchangeDefinitiontypes.ts:1019
messagepublicMessageDefinitiontypes.ts:1021
queuepublicQueueDefinitiontypes.ts:1020
routingKeypublicstring | undefinedtypes.ts:1022

CompressionAlgorithm ​

ts
type CompressionAlgorithm = "gzip" | "deflate";

Defined in: types.ts:206

Supported compression algorithms for message payloads.

  • gzip: GZIP compression (standard, widely supported, good compression ratio)
  • deflate: DEFLATE compression (faster than gzip, slightly less compression)

Compression is configured at runtime via PublishOptions when calling AmqpClient.publish, not at publisher definition time.

When compression is enabled, the message payload is compressed before publishing and automatically decompressed when consuming. The content-encoding AMQP message property is set to indicate the compression algorithm used.

To disable compression, simply omit the compression option (it's optional).

Example ​

typescript
// Define a publisher without compression configuration
const orderCreatedPublisher = definePublisher(exchange, message, {
  routingKey: "order.created",
});

// Later, choose whether to compress at publish time
await client.publish("orderCreated", payload, {
  compression: "gzip",
});

ConsumerDefinition ​

ts
type ConsumerDefinition<TMessage> = object;

Defined in: types.ts:976

Definition of a message consumer.

A consumer receives and processes messages from a queue with automatic schema validation. The message payload is validated against the schema before being passed to your handler. If the message is compressed (indicated by the content-encoding header), it will be automatically decompressed before validation.

Example ​

typescript
const consumer: ConsumerDefinition = {
  queue: orderProcessingQueue,
  message: orderMessage
};

Type Parameters ​

Type ParameterDefault typeDescription
TMessage extends MessageDefinitionMessageDefinitionThe message definition with payload schema

Properties ​

PropertyTypeDescriptionDefined in
messageTMessageThe message definition including the payload schematypes.ts:981
queueQueueDefinitionThe queue to consume messages fromtypes.ts:978

ConsumerEntry ​

ts
type ConsumerEntry = 
  | ConsumerDefinition
  | EventConsumerResultBase
  | CommandConsumerConfigBase;

Defined in: types.ts:1221

Consumer entry that can be passed to defineContract's consumers section.

Can be either:

  • A plain ConsumerDefinition from defineConsumer
  • An EventConsumerResult from defineEventConsumer (binding auto-extracted)
  • A CommandConsumerConfig from defineCommandConsumer (binding auto-extracted)

ContractBinding ​

ts
type ContractBinding = object;

Defined in: contract-binding.ts:12

Explicit physical names for resources present in a normalized contract.

Properties ​

PropertyTypeDefined in
exchanges?Readonly<Record<string, string>>contract-binding.ts:13
queues?Readonly<Record<string, string>>contract-binding.ts:14

ContractDefinition ​

ts
type ContractDefinition = object;

Defined in: types.ts:1151

Complete AMQP contract definition (output type).

A contract brings together all AMQP resources into a single, type-safe definition. It defines the complete messaging topology including exchanges, queues, bindings, publishers, and consumers.

The contract is used by:

  • Clients (TypedAmqpClient) for type-safe message publishing
  • Workers (TypedAmqpWorker) for type-safe message consumption
  • AsyncAPI generator for documentation

Example ​

typescript
const contract: ContractDefinition = {
  exchanges: {
    orders: ordersExchange,
  },
  queues: {
    orderProcessing: orderProcessingQueue,
  },
  bindings: {
    orderBinding: orderQueueBinding,
  },
  publishers: {
    orderCreated: orderCreatedPublisher,
  },
  consumers: {
    processOrder: processOrderConsumer,
  },
};

Properties ​

PropertyTypeDescriptionDefined in
bindings?Record<string, BindingDefinition>Named binding definitions. Bindings can be queue-to-exchange or exchange-to-exchange.types.ts:1172
consumers?Record<string, ConsumerDefinition>Named consumer definitions. Each key requires a corresponding handler in the TypedAmqpWorker. The handler will be fully typed based on the message schema.types.ts:1186
exchanges?Record<string, ExchangeDefinition>Named exchange definitions. Each key becomes available as a named resource in the contract.types.ts:1156
publishers?Record<string, PublisherDefinition>Named publisher definitions. Each key becomes a method on the TypedAmqpClient for publishing messages. The method will be fully typed based on the message schema.types.ts:1179
queues?Record<string, QueueDefinition>Named queue definitions. Each key becomes available as a named resource in the contract. Queues with TTL-backoff retry configured are plain QueueDefinitions; their wait queues are derived and declared at topology-setup time, not stored in the contract.types.ts:1166
rpcs?Record<string, RpcDefinition>Named RPC definitions. Each key gets: - A handler in the TypedAmqpWorker that returns the typed response. - A client.call(name, request, options) method on the TypedAmqpClient. RPC entries do not appear in publishers or consumers because each end of an RPC plays both roles (publisher of one direction, consumer of the other).types.ts:1197

ContractDefinitionInput ​

ts
type ContractDefinitionInput = object;

Defined in: types.ts:1250

Contract definition input type with automatic extraction of event/command patterns.

Users only define publishers and consumers. Exchanges, queues, and bindings are automatically extracted from these definitions.

Example ​

typescript
const contract = defineContract({
  publishers: {
    // EventPublisherConfig → auto-extracted to publisher
    orderCreated: defineEventPublisher(ordersExchange, orderMessage, { routingKey: "order.created" }),
  },
  consumers: {
    // CommandConsumerConfig → auto-extracted to consumer + binding
    processOrder: defineCommandConsumer(orderQueue, ordersExchange, orderMessage, { routingKey: "order.process" }),
    // EventConsumerResult → auto-extracted to consumer + binding
    notify: defineEventConsumer(orderCreatedEvent, notificationQueue),
  },
});

See ​

defineContract - Processes this input and returns a ContractDefinition

Properties ​

PropertyTypeDescriptionDefined in
bindings?Record<string, BindingDefinition>Standalone bindings — e.g. binding a declared DLQ to the dead-letter exchange. Keys are used verbatim as the binding labels in the output.types.ts:1298
consumers?Record<string, ConsumerEntry>Named consumer definitions. Can accept: - ConsumerDefinition from defineConsumer - EventConsumerResult from defineEventConsumer (binding auto-extracted) - CommandConsumerConfig from defineCommandConsumer (binding auto-extracted)types.ts:1268
exchanges?Record<string, ExchangeDefinition>Standalone exchanges — topology this service asserts without publishing to it (e.g. an exchange owned by another domain that bindings reference). Keys are authoring labels; the contract output keys exchanges by name.types.ts:1282
publishers?Record<string, PublisherEntry>Named publisher definitions. Can accept: - PublisherDefinition from definePublisher - EventPublisherConfig from defineEventPublisher (auto-extracted to publisher)types.ts:1258
queues?Record<string, QueueDefinition>Standalone queues — queues with no consumer in this service, asserted by setupAmqpTopology all the same. The classic cases: a DLQ bound to the auto-extracted dead-letter exchange, or an audit queue that another process drains. Dead-letter exchanges are auto-extracted exactly as for consumer queues. Keys are authoring labels; the contract output keys queues by name.types.ts:1292
rpcs?Record<string, RpcDefinition>Named RPC definitions from defineRpc. Each entry contributes its queue (and DLX if any) to the contract topology and exposes a typed client.call(name, ...) / worker handler pair.types.ts:1275

ContractOutput ​

ts
type ContractOutput<TContract> = object;

Defined in: types.ts:1633

Contract output type with all resources extracted and properly typed.

This type represents the fully expanded contract with:

  • exchanges: Extracted from publishers and consumer bindings, plus standalone declarations
  • queues: Extracted from consumers and RPCs, plus standalone declarations
  • bindings: Extracted from event/command consumers, plus standalone declarations
  • publishers: Normalized publisher definitions
  • consumers: Normalized consumer definitions

Type Parameters ​

Type Parameter
TContract extends ContractDefinitionInput

Properties ​

PropertyTypeDefined in
bindings(TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractBindingsFromConsumers<TContract["consumers"]> : object) & (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractExchangeBindingsFromConsumers<TContract["consumers"]> : object) & (TContract["publishers"] extends Record<string, PublisherEntry> ? ExtractExchangeBindingsFromPublishers<TContract["publishers"]> : object) & (TContract["bindings"] extends Record<string, BindingDefinition> ? TContract["bindings"] : object)types.ts:1667
consumersTContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractConsumerDefinitions<TContract["consumers"]> : objecttypes.ts:1680
exchanges(TContract["publishers"] extends Record<string, PublisherEntry> ? ExtractExchangesFromPublishers<TContract["publishers"]> : object) & (TContract["exchanges"] extends Record<string, ExchangeDefinition> ? ExtractStandaloneExchanges<TContract["exchanges"]> : object) & (TContract["queues"] extends Record<string, QueueDefinition> ? ExtractDeadLetterExchangesFromStandaloneQueues<TContract["queues"]> : object) & (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractExchangesFromConsumers<TContract["consumers"]> : object) & (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractDeadLetterExchangesFromConsumers<TContract["consumers"]> : object) & (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractBridgeExchangesFromConsumers<TContract["consumers"]> : object) & (TContract["publishers"] extends Record<string, PublisherEntry> ? ExtractTargetExchangesFromPublishers<TContract["publishers"]> : object) & (TContract["rpcs"] extends Record<string, RpcDefinition> ? ExtractDeadLetterExchangesFromRpcs<TContract["rpcs"]> : object)types.ts:1634
publishersTContract["publishers"] extends Record<string, PublisherEntry> ? ExtractPublisherDefinitions<TContract["publishers"]> : objecttypes.ts:1677
queues(TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractQueuesFromConsumers<TContract["consumers"]> : object) & (TContract["rpcs"] extends Record<string, RpcDefinition> ? ExtractQueuesFromRpcs<TContract["rpcs"]> : object) & (TContract["queues"] extends Record<string, QueueDefinition> ? ExtractStandaloneQueues<TContract["queues"]> : object)types.ts:1658
rpcsTContract["rpcs"] extends Record<string, RpcDefinition> ? TContract["rpcs"] : objecttypes.ts:1683

DeadLetterConfig ​

ts
type DeadLetterConfig = object;

Defined in: types.ts:550

Configuration for dead letter exchange (DLX) on a queue.

When a message in a queue is rejected, expires, or exceeds the queue length limit, it can be automatically forwarded to a dead letter exchange for further processing or storage.

Properties ​

PropertyTypeDescriptionDefined in
exchangeExchangeDefinitionThe exchange to send dead-lettered messages to. This exchange must be declared in the contract.types.ts:555
externalConsumers?booleanDeclares that the queue bound to this dead-letter exchange lives outside this contract — another service, or infrastructure-as-code, owns it. defineContract otherwise requires a declared binding from the exchange, because a dead-letter exchange with nothing bound to it discards every message routed to it, exactly as silently as an unroutable publish. Named to match PublisherDefinition.externalConsumers: the concept is identical — the consuming side is not this contract's to declare.types.ts:574
routingKey?stringOptional routing key to use when forwarding messages to the dead letter exchange. If not specified, the original message routing key is used.types.ts:561

DeadLetterQueue ​

ts
type DeadLetterQueue<TName> = object;

Defined in: builder/dead-letter-queue.ts:34

A dead-letter queue and the binding that delivers to it — add both to the contract: queues: { dlq: dlq.queue }, bindings: { dlq: dlq.binding }.

Type Parameters ​

Type ParameterDefault type
TName extends stringstring

Properties ​

PropertyTypeDescriptionDefined in
bindingQueueBindingDefinitionThe binding from the dead-letter exchange to DeadLetterQueue.queue.builder/dead-letter-queue.ts:38
queueQueueDefinition<TName>The dead-letter queue.builder/dead-letter-queue.ts:36

DefineQueueOptions ​

ts
type DefineQueueOptions = 
  | QuorumQueueOptions
  | ClassicQueueOptions;

Defined in: types.ts:411

Options for defining a queue. Uses a discriminated union based on the type property to enforce quorum queue constraints at compile time.

  • Quorum queues (default): Do not support exclusive, autoDelete, or maxPriority (they prioritise messages natively on RabbitMQ 4.0+, without x-max-priority)
  • Classic queues: Support all options including exclusive, autoDelete, and maxPriority

DefineQueueOptionsWithDeadLetterExchange ​

ts
type DefineQueueOptionsWithDeadLetterExchange<TDlx> = DefineQueueOptions & object;

Defined in: types.ts:416

Options for defining a queue with a dead letter exchange.

Type Parameters ​

Type ParameterDefault type
TDlx extends ExchangeDefinitionExchangeDefinition

Type Declaration ​

NameTypeDefined in
deadLetterobjecttypes.ts:418
deadLetter.exchangeTDlxtypes.ts:418

DirectExchangeDefinition ​

ts
type DirectExchangeDefinition<TName> = BaseExchangeDefinition<TName> & object;

Defined in: types.ts:491

A direct exchange definition.

Direct exchanges route messages to queues based on exact routing key matches. This is ideal for point-to-point messaging where each message should go to specific queues.

Type Parameters ​

Type ParameterDefault type
TName extends stringstring

Type Declaration ​

NameTypeDefined in
type"direct"types.ts:493

Example ​

typescript
const tasksExchange: DirectExchangeDefinition = defineExchange('tasks', {
  type: 'direct',
});

EventConsumerResult ​

ts
type EventConsumerResult<TMessage, TExchange, TQueue, TExchangeBinding, TBridgeExchange> = object;

Defined in: builder/event.ts:78

Result from defineEventConsumer.

Contains the consumer definition and binding needed to subscribe to an event. Can be used directly in defineContract's consumers section - the binding will be automatically extracted.

Type Parameters ​

Type ParameterDefault typeDescription
TMessage extends MessageDefinition-The message definition
TExchange extends ExchangeDefinitionExchangeDefinition-
TQueue extends QueueDefinitionQueueDefinition-
TExchangeBinding extends ExchangeBindingDefinition | undefinedExchangeBindingDefinition | undefined-
TBridgeExchange extends ExchangeDefinition | undefinedExchangeDefinition | undefined-

Properties ​

PropertyModifierTypeDescriptionDefined in
[brand]readonly"EventConsumerResult"Discriminator to identify this as an event consumer resultbuilder/event.ts:88
bindingpublicQueueBindingDefinitionThe binding connecting the queue to the exchangebuilder/event.ts:92
bridgeExchangepublicTBridgeExchangeThe bridge (local domain) exchange when bridging, if configuredbuilder/event.ts:100
consumerpublicConsumerDefinition<TMessage>The consumer definition for processing messagesbuilder/event.ts:90
exchangepublicTExchangeThe source exchange this consumer subscribes tobuilder/event.ts:94
exchangeBindingpublicTExchangeBindingThe exchange-to-exchange binding when bridging, if configuredbuilder/event.ts:98
queuepublicTQueueThe queue this consumer reads frombuilder/event.ts:96

EventConsumerResultBase ​

ts
type EventConsumerResultBase = object;

Defined in: types.ts:1033

Base type for event consumer result.

This is a simplified type used in ContractDefinitionInput. The full generic type is defined in the builder module.

See ​

defineEventConsumer for creating event consumers

Properties ​

PropertyModifierTypeDefined in
[brand]readonly"EventConsumerResult"types.ts:1034
bindingpublicQueueBindingDefinitiontypes.ts:1036
bridgeExchangepublicExchangeDefinition | undefinedtypes.ts:1040
consumerpublicConsumerDefinitiontypes.ts:1035
exchangepublicExchangeDefinitiontypes.ts:1037
exchangeBindingpublicExchangeBindingDefinition | undefinedtypes.ts:1039
queuepublicQueueDefinitiontypes.ts:1038

EventPublisherConfig ​

ts
type EventPublisherConfig<TMessage, TExchange, TRoutingKey> = object;

Defined in: builder/event.ts:36

Configuration for an event publisher.

Events are published without knowing who consumes them. Multiple consumers can subscribe to the same event. This follows the pub/sub pattern where publishers broadcast events and consumers subscribe to receive them.

Type Parameters ​

Type ParameterDefault typeDescription
TMessage extends MessageDefinition-The message definition
TExchange extends ExchangeDefinition-The exchange definition
TRoutingKey extends string | undefinedundefinedThe routing key type (undefined for fanout and headers exchanges)

Properties ​

PropertyModifierTypeDescriptionDefined in
[brand]readonly"EventPublisherConfig"Discriminator to identify this as an event publisher configbuilder/event.ts:42
bindingArguments?publicRecord<string, unknown>Default AMQP binding arguments for consumers of this event. These are NOT publish arguments — they are applied to the queue binding of every defineEventConsumer of this event that does not pass its own arguments option.builder/event.ts:56
exchangepublicTExchangeThe exchange to publish tobuilder/event.ts:44
externalConsumers?publicbooleanDeclares that this event's consumers live outside this contract — a separate service or deployment owns the binding. Carried onto the publisher definition that defineContract extracts, so it opts the event out of the define-time routability check. See PublisherDefinition.externalConsumersbuilder/event.ts:66
messagepublicTMessageThe message definitionbuilder/event.ts:46
routingKeypublicTRoutingKeyThe routing key for direct/topic exchangesbuilder/event.ts:48

EventPublisherConfigBase ​

ts
type EventPublisherConfigBase = object;

Defined in: types.ts:996

Base type for event publisher configuration.

This is a simplified type used in ContractDefinition. The full generic type is defined in the builder module.

See ​

defineEventPublisher for creating event publishers

Properties ​

PropertyModifierTypeDescriptionDefined in
[brand]readonly"EventPublisherConfig"-types.ts:997
bindingArguments?publicRecord<string, unknown>Default binding arguments for this event's consumers (not publish arguments).types.ts:1002
exchangepublicExchangeDefinition-types.ts:998
externalConsumers?publicbooleanOpt out of the define-time routability check — see PublisherDefinition.externalConsumers.types.ts:1004
messagepublicMessageDefinition-types.ts:999
routingKeypublicstring | undefined-types.ts:1000

ExchangeBindingDefinition ​

ts
type ExchangeBindingDefinition = object & (
  | {
  routingKey: string;
  source:   | DirectExchangeDefinition
     | TopicExchangeDefinition;
}
  | {
  routingKey?: never;
  source:   | FanoutExchangeDefinition
     | HeadersExchangeDefinition;
});

Defined in: types.ts:869

Binding between two exchanges (exchange-to-exchange routing).

Defines how messages should be forwarded from a source exchange to a destination exchange. This allows for more complex routing topologies.

Type Declaration ​

NameTypeDescriptionDefined in
arguments?Record<string, unknown>Additional AMQP arguments for the binding.types.ts:879
destinationExchangeDefinitionThe destination exchange that will receive forwarded messagestypes.ts:874
type"exchange"Discriminator indicating this is an exchange-to-exchange bindingtypes.ts:871

Example ​

typescript
// Forward high-priority orders to a special processing exchange
const binding: ExchangeBindingDefinition = {
  type: 'exchange',
  source: ordersExchange,
  destination: highPriorityExchange,
  routingKey: 'order.high-priority.*'
};

ExchangeDefinition ​

ts
type ExchangeDefinition<TName> = 
  | TopicExchangeDefinition<TName>
  | DirectExchangeDefinition<TName>
  | FanoutExchangeDefinition<TName>
  | HeadersExchangeDefinition<TName>;

Defined in: types.ts:537

Union type of all exchange definitions.

Represents any type of AMQP exchange: topic, direct, fanout, headers.

Type Parameters ​

Type ParameterDefault type
TName extends stringstring

FanoutExchangeDefinition ​

ts
type FanoutExchangeDefinition<TName> = BaseExchangeDefinition<TName> & object;

Defined in: types.ts:509

A fanout exchange definition.

Fanout exchanges broadcast all messages to all bound queues, ignoring routing keys. This is the simplest exchange type for pub/sub messaging patterns.

Type Parameters ​

Type ParameterDefault type
TName extends stringstring

Type Declaration ​

NameTypeDefined in
type"fanout"types.ts:511

Example ​

typescript
const logsExchange: FanoutExchangeDefinition = defineExchange('logs', {
  type: 'fanout',
});

HeadersExchangeDefinition ​

ts
type HeadersExchangeDefinition<TName> = BaseExchangeDefinition<TName> & object;

Defined in: types.ts:527

A headers exchange definition.

Headers exchanges route messages based on header values rather than routing keys. This is useful for more complex routing scenarios where metadata is important.

Type Parameters ​

Type ParameterDefault type
TName extends stringstring

Type Declaration ​

NameTypeDefined in
type"headers"types.ts:529

Example ​

typescript
const routesExchange: HeadersExchangeDefinition = defineExchange('routes', {
  type: 'headers',
});

ImmediateRequeueRetryOptions ​

ts
type ImmediateRequeueRetryOptions = object;

Defined in: types.ts:102

Immediate-Requeue retry options.

Failed messages are requeued immediately. For quorum queues, messages are requeued with nack(requeue=true), and the worker tracks delivery count via the native RabbitMQ x-delivery-count header. For classic queues, messages are re-published on the same queue, and the worker tracks delivery count via a custom x-retry-count header. When the count exceeds maxRetries, the message is automatically dead-lettered (if DLX is configured) or dropped.

On a quorum queue, defineQueue also sets the x-delivery-limit queue argument to maxRetries + 1 (RabbitMQ 4.x defaults it to 20 and dead-letters past it, which would pre-empt a worker counting to 20 or more). An explicit x-delivery-limit in arguments is kept, and rejected if it is below maxRetries + 1.

Benefits: Simpler architecture, no wait queues needed, no head-of-queue blocking. Limitation: Immediate retries only (no exponential backoff).

See ​

https://www.rabbitmq.com/docs/quorum-queues#poison-message-handling

Properties ​

PropertyTypeDescriptionDefined in
maxRetries?numberMaximum retry attempts before sending to DLQ. Minimum 1 - Must be a positive integer (1 or greater) Default 3types.ts:112
mode"immediate-requeue"Immediate-Requeue mode.types.ts:106

InferConsumerNames ​

ts
type InferConsumerNames<TContract> = TContract["consumers"] extends Record<string, unknown> ? keyof TContract["consumers"] : never;

Defined in: types.ts:1719

Extract consumer names from a contract.

This utility type extracts the keys of all consumers defined in a contract. It's used internally for type inference in the TypedAmqpWorker.

Type Parameters ​

Type ParameterDescription
TContract extends ContractDefinitionThe contract definition

Returns ​

Union of consumer names, or never if no consumers defined

Example ​

typescript
type ConsumerNames = InferConsumerNames<typeof myContract>;
// Result: 'processOrder' | 'sendNotification' | 'updateInventory'

InferPublisherNames ​

ts
type InferPublisherNames<TContract> = TContract["publishers"] extends Record<string, unknown> ? keyof TContract["publishers"] : never;

Defined in: types.ts:1701

Extract publisher names from a contract.

This utility type extracts the keys of all publishers defined in a contract. It's used internally for type inference in the TypedAmqpClient.

Type Parameters ​

Type ParameterDescription
TContract extends ContractDefinitionThe contract definition

Returns ​

Union of publisher names, or never if no publishers defined

Example ​

typescript
type PublisherNames = InferPublisherNames<typeof myContract>;
// Result: 'orderCreated' | 'orderUpdated' | 'orderCancelled'

InferRpcNames ​

ts
type InferRpcNames<TContract> = TContract["rpcs"] extends Record<string, RpcDefinition> ? keyof TContract["rpcs"] : never;

Defined in: types.ts:1731

Extract RPC names from a contract.

Each name in this union has a typed worker handler and a client.call(name, ...) method. RPC names are disjoint from InferConsumerNames and InferPublisherNames.

Type Parameters ​

Type ParameterDescription
TContract extends ContractDefinitionThe contract definition

Returns ​

Union of RPC names, or never if no RPCs defined


InferSchemaInput ​

ts
type InferSchemaInput<TSchema> = TSchema extends StandardSchemaV1<infer TInput> ? TInput : never;

Defined in: types.ts:24

Infer a Standard Schema's INPUT type — what callers hand to validation (publish payloads, RPC requests) before defaults and transforms run.

Canonical home of the helper the client and worker packages alias, so a contract-only package can derive payload types without depending on either: type OrderCreated = InferSchemaInput<typeof contract.publishers.orderCreated.message.payload>.

Type Parameters ​

Type Parameter
TSchema extends StandardSchemaV1

InferSchemaOutput ​

ts
type InferSchemaOutput<TSchema> = TSchema extends StandardSchemaV1<infer _TInput, infer TOutput> ? TOutput : never;

Defined in: types.ts:31

Infer a Standard Schema's OUTPUT type — what validation produces (defaults applied, transforms run); the shape handlers and RPC callers receive.

Type Parameters ​

Type Parameter
TSchema extends StandardSchemaV1

MatchingBindingPattern ​

ts
type MatchingBindingPattern<Pattern, PublisherKey> = IsStringLiteral<Pattern> extends false ? BindingPattern<Pattern> : IsStringLiteral<PublisherKey> extends false ? BindingPattern<Pattern> : [BindingPattern<Pattern>] extends [never] ? never : MatchesPattern<PublisherKey, Pattern> extends true ? Pattern : `Error: binding pattern '${Pattern}' can never match the publisher routing key '${PublisherKey}'`;

Defined in: builder/routing-types.ts:213

Binding pattern for a topic consumer, validated against the publisher's concrete routing key.

defineEventConsumer uses this on its topic overloads: a routing-key override must be a pattern that can actually match the event publisher's routing key, otherwise the binding compiles but silently receives nothing at runtime. On a mismatch this resolves to a human-readable error-message string type — so the compile error names both sides instead of collapsing to a bare never:

Type '"user.*"' is not assignable to type
  "Error: binding pattern 'user.*' can never match the publisher routing key 'order.created'"

The check runs only when both sides are fully known at compile time. Plain string, a template-literal type with a ${…} hole (`${string}.created`), and any union containing either are skipped: the match cannot be decided, and guessing would reject a pattern that matches at runtime. The define-time routability check in defineContract does not cover the gap this leaves: it fails a contract whose publisher reaches no queue, but it does not detect a consumer binding like this one that receives nothing while a sibling binding keeps the publisher routable. There is no compile-time or define-time backstop for that case.

Type Parameters ​

Type ParameterDescription
Pattern extends stringThe consumer's binding pattern (can contain * and # wildcards)
PublisherKey extends stringThe publisher's concrete routing key

MatchingRoutingKey ​

ts
type MatchingRoutingKey<Pattern, Key> = RoutingKey<Key> extends never ? never : BindingPattern<Pattern> extends never ? never : IsStringLiteral<Pattern> extends false ? Key : IsStringLiteral<Key> extends false ? Key : MatchesPattern<Key, Pattern> extends true ? Key : never;

Defined in: builder/routing-types.ts:171

Validate that a routing key matches a binding pattern.

This is a utility type for users who want compile-time validation that a routing key matches a specific pattern. The library enforces the same matching on defineEventConsumer's topic routing-key overrides via MatchingBindingPattern (which surfaces a readable error-message string type instead of never).

Returns the routing key when both the pattern and the key are valid (see RoutingKey and BindingPattern) and the key matches the pattern; never when either is invalid or the key does not match — so MatchingRoutingKey<"order.*", "order.*"> is never: the key matches the pattern textually, but a routing key may not itself contain a wildcard.

Each side's validity (RoutingKey for Key, BindingPattern for Pattern) is always enforced, even when the other side is not fully known — validity is decidable from one side alone. Only the match between the two is skipped when either side is not a fully known compile-time literal: plain string, a template-literal type, or a union containing either resolves to Key unchecked once both sides pass their own validity check — the match cannot be decided, and guessing would reject a key that routes at runtime.

Type Parameters ​

Type ParameterDescription
Pattern extends stringThe binding pattern (can contain * and # wildcards)
Key extends stringThe routing key to validate

Example ​

typescript
type ValidKey = MatchingRoutingKey<"order.*", "order.created">; // "order.created"
type InvalidKey = MatchingRoutingKey<"order.*", "user.created">; // never

MessageDefinition ​

ts
type MessageDefinition<TPayload, THeaders> = object;

Defined in: types.ts:783

Definition of a message with typed payload and optional headers.

Type Parameters ​

Type ParameterDefault typeDescription
TPayload extends AnySchemaAnySchemaThe Standard Schema v1 compatible schema for the message payload
THeaders extends | StandardSchemaV1<Record<string, unknown>> | undefined| StandardSchemaV1<Record<string, unknown>> | undefinedThe Standard Schema v1 compatible schema for the message headers (optional)

Properties ​

PropertyTypeDescriptionDefined in
description?stringDetailed description of the message for documentation purposes. Used in AsyncAPI specification generation.types.ts:811
headers?THeadersOptional headers schema for validating message metadata. Must be a Standard Schema v1 compatible schema.types.ts:799
payloadTPayloadThe payload schema for validating message content. Must be a Standard Schema v1 compatible schema (Zod, Valibot, ArkType, etc.).types.ts:793
summary?stringBrief description of the message for documentation purposes. Used in AsyncAPI specification generation.types.ts:805

NoneRetryOptions ​

ts
type NoneRetryOptions = object;

Defined in: types.ts:119

No retry mode. Failed messages are not retried and are sent directly to DLQ (if configured) or rejected.

Properties ​

PropertyTypeDescriptionDefined in
mode"none"None mode disables retry attempts entirely.types.ts:123

PublisherDefinition ​

ts
type PublisherDefinition<TMessage> = object & (
  | {
  exchange:   | DirectExchangeDefinition
     | TopicExchangeDefinition;
  routingKey: string;
}
  | {
  exchange:   | FanoutExchangeDefinition
     | HeadersExchangeDefinition;
  routingKey?: never;
});

Defined in: types.ts:927

Definition of a message publisher.

A publisher sends messages to an exchange with automatic schema validation. The message payload is validated against the schema before being sent to RabbitMQ.

Compression can be optionally applied at publish time by specifying a compression algorithm when calling the publish method.

Type Parameters ​

Type ParameterDefault typeDescription
TMessage extends MessageDefinitionMessageDefinitionThe message definition with payload schema

Type Declaration ​

NameTypeDescriptionDefined in
externalConsumers?booleanDeclares that this publisher's consumers live outside this contract — a separate service or deployment owns the binding. Routability cannot be verified for such a publisher, so the define-time check is skipped. This is deliberately explicit: a heuristic ("no bindings at all means external") would silently miss the mistyped-key case the check exists to catch.types.ts:939
messageTMessageThe message definition including the payload schematypes.ts:929

Example ​

typescript
const publisher: PublisherDefinition = {
  exchange: ordersExchange,
  message: orderMessage,
  routingKey: 'order.created'
};

PublisherEntry ​

ts
type PublisherEntry = 
  | PublisherDefinition
  | EventPublisherConfigBase
  | BridgedPublisherConfigBase;

Defined in: types.ts:1208

Publisher entry that can be passed to defineContract's publishers section.

Can be either:

  • A plain PublisherDefinition from definePublisher
  • An EventPublisherConfig from defineEventPublisher (auto-extracted to publisher)
  • An BridgedPublisherConfig from defineCommandPublisher (auto-extracted to publisher)

QueueBindingDefinition ​

ts
type QueueBindingDefinition = object & (
  | {
  exchange:   | DirectExchangeDefinition
     | TopicExchangeDefinition;
  routingKey: string;
}
  | {
  exchange:   | FanoutExchangeDefinition
     | HeadersExchangeDefinition;
  routingKey?: never;
});

Defined in: types.ts:821

Binding between a queue and an exchange.

Defines how messages from an exchange should be routed to a queue. For direct and topic exchanges, a routing key is required. For fanout and headers exchanges, no routing key is needed.

Type Declaration ​

NameTypeDescriptionDefined in
arguments?Record<string, unknown>Additional AMQP arguments for the binding. Can be used for advanced routing scenarios with the headers exchange type.types.ts:832
queueQueueDefinitionThe queue that will receive messagestypes.ts:826
type"queue"Discriminator indicating this is a queue-to-exchange bindingtypes.ts:823

QueueDefinition ​

ts
type QueueDefinition<TName> = 
  | QuorumQueueDefinition<TName>
  | ClassicQueueDefinition<TName>;

Defined in: types.ts:709

Definition of an AMQP queue.

A discriminated union based on queue type:

  • QuorumQueueDefinition: For quorum queues (type: "quorum")
  • ClassicQueueDefinition: For classic queues (type: "classic")

Use queue.type as the discriminator to narrow the type.

Type Parameters ​

Type ParameterDefault type
TName extends stringstring

QueueDefinitionWithDeadLetterExchange ​

ts
type QueueDefinitionWithDeadLetterExchange<TName, TDlx> = QueueDefinition<TName> & object;

Defined in: types.ts:770

A queue definition with a dead letter exchange.

Type Parameters ​

Type ParameterDefault type
TName extends stringstring
TDlx extends ExchangeDefinitionExchangeDefinition

Type Declaration ​

NameTypeDefined in
deadLetterobjecttypes.ts:774
deadLetter.exchangeTDlxtypes.ts:774

QueueType ​

ts
type QueueType = "quorum" | "classic";

Defined in: types.ts:238

Supported queue types in RabbitMQ.

  • quorum: Quorum queues (default, recommended) - Provide better durability and high-availability using the Raft consensus algorithm. Best for most production use cases.
  • classic: Classic queues - The traditional RabbitMQ queue type. Use only when you need specific features not supported by quorum queues (e.g., non-durable, exclusive or auto-deleting queues, or x-max-priority priority levels).

Note: Quorum queues only support durable queues, and do not support exclusive or auto-deleting queues. They do support message priority natively on RabbitMQ 4.0+ — the per-message priority property, with no queue argument (normal vs high above 4 on 4.0–4.2; 32 strict levels on 4.3+) — so maxPriority (x-max-priority, which quorum queues ignore) is classic-only.

See ​

https://www.rabbitmq.com/docs/quorum-queues

Example ​

typescript
// Create a quorum queue (default, recommended)
const orderQueue = defineQueue('order-processing', {
  type: 'quorum', // This is the default
});

// Create a classic queue (for special cases)
const tempQueue = defineQueue('temp-queue', {
  type: 'classic',
  durable: false, // Only supported with classic queues
});

QuorumQueueDefinition ​

ts
type QuorumQueueDefinition<TName> = BaseQueueDefinition<TName> & object;

Defined in: types.ts:631

Definition of a quorum queue.

Quorum queues provide better durability and high-availability using the Raft consensus algorithm.

Type Parameters ​

Type ParameterDefault type
TName extends stringstring

Type Declaration ​

NameTypeDescriptionDefined in
autoDelete?neverQuorum queues do not support auto-delete mode. Use type: 'classic' if you need auto-deleting queues.types.ts:652
durabletrueQuorum queues only support durable queues.types.ts:640
exclusive?neverQuorum queues do not support exclusive mode. Use type: 'classic' if you need exclusive queues.types.ts:646
maxPriority?neverx-max-priority is a classic-queue argument; quorum queues ignore it. Quorum queues honor the per-message priority property natively on RabbitMQ 4.0+ (normal vs high above 4 on 4.0–4.2; 32 strict levels on 4.3+) — publish with priority and leave this unset. Use type: 'classic' only if you need classic priority levels.types.ts:661
type"quorum"Queue type discriminator: quorum queue.types.ts:635

QuorumQueueOptions ​

ts
type QuorumQueueOptions = BaseQueueOptions & object;

Defined in: types.ts:323

Options for creating a quorum queue.

Quorum queues do not support:

  • exclusive - Use classic queues for connection-scoped queues
  • autoDelete - Use classic queues for auto-deleting queues when consumers disconnect
  • maxPriority - x-max-priority is classic-only; quorum queues honor the per-message priority property natively on RabbitMQ 4.0+ with no queue argument
  • durable: false - Use classic queues for non-durable queues

Quorum queues provide native retry support for immediate-requeue retry mode:

  • RabbitMQ tracks delivery count automatically via x-delivery-count header
  • When the limit is exceeded, messages are dead-lettered (if DLX is configured) or dropped
  • x-delivery-limit is set to maxRetries + 1 so the broker's own cap (default 20 on RabbitMQ 4.x) never dead-letters before the worker's retry budget is spent
  • This is simpler than TTL-based retry and avoids head-of-queue blocking issues

Type Declaration ​

NameTypeDescriptionDefined in
autoDelete?neverQuorum queues do not support auto-delete mode. Use type: 'classic' if you need auto-deleting queues.types.ts:344
durable?trueQuorum queues only support durable queues.types.ts:332
exclusive?neverQuorum queues do not support exclusive mode. Use type: 'classic' if you need exclusive queues.types.ts:338
maxPriority?neverx-max-priority is a classic-queue argument; quorum queues ignore it. Quorum queues honor the per-message priority property natively on RabbitMQ 4.0+ (normal vs high above 4 on 4.0–4.2; 32 strict levels on 4.3+) — publish with priority and leave this unset. Use type: 'classic' only if you need classic priority levels.types.ts:353
type?"quorum"Queue type: quorum (default, recommended)types.ts:327

Example ​

typescript
const orderQueue = defineQueue('orders', {
  type: 'quorum',
  deadLetter: { exchange: dlx },
  retry: { mode: 'immediate-requeue', maxRetries: 3 } // Message dead-lettered after 3 retry attempts
});

ResolvedImmediateRequeueRetryOptions ​

ts
type ResolvedImmediateRequeueRetryOptions = object;

Defined in: types.ts:157

Resolved Immediate-Requeue retry options with all defaults applied.

This is what queue definitions carry after defineQueue has applied default values. All fields are required.

Properties ​

PropertyTypeDefined in
maxRetriesnumbertypes.ts:159
mode"immediate-requeue"types.ts:158

ResolvedRetryOptions ​

ts
type ResolvedRetryOptions = 
  | NoneRetryOptions
  | ResolvedImmediateRequeueRetryOptions
  | ResolvedTtlBackoffRetryOptions;

Defined in: types.ts:173

Resolved retry configuration stored in queue definitions.

This is a discriminated union based on the mode field:

  • none: No retry attempts are made; failed messages are handled by DLQ/reject
  • immediate-requeue: Has all immediate-requeue retry options with default applied
  • ttl-backoff: Has all TTL-backoff retry options with defaults applied

When using ttl-backoff mode, setupAmqpTopology derives and declares one wait queue per distinct backoff delay (see deriveTtlBackoffInfrastructure).


ResolvedTtlBackoffRetryOptions ​

ts
type ResolvedTtlBackoffRetryOptions = object;

Defined in: types.ts:142

Resolved TTL-Backoff retry options with all defaults applied.

This is what queue definitions carry after defineQueue has applied default values. All fields are required.

Properties ​

PropertyTypeDefined in
backoffMultipliernumbertypes.ts:147
initialDelayMsnumbertypes.ts:145
jitterbooleantypes.ts:148
maxDelayMsnumbertypes.ts:146
maxRetriesnumbertypes.ts:144
mode"ttl-backoff"types.ts:143

RetryOptions ​

ts
type RetryOptions = 
  | NoneRetryOptions
  | ImmediateRequeueRetryOptions
  | TtlBackoffRetryOptions;

Defined in: types.ts:134

Retry configuration options.

This is a discriminated union based on the mode field:

  • none (default): No retry attempts are made; failed messages are handled by DLQ/reject
  • immediate-requeue: Requeues failed messages immediately
  • ttl-backoff: Uses wait queues with exponential backoff

RoutableRoutingKey ​

ts
type RoutableRoutingKey<Key, Patterns> = IsStringLiteral<Key> extends false ? Key : IsStringLiteral<Patterns> extends false ? Key : MatchesAnyPattern<Key, Patterns> extends true ? Key : `Error: routing key '${Key}' matches none of the declared binding patterns; the broker would confirm and discard every message`;

Defined in: builder/routing-types.ts:268

A publisher routing key validated against the binding patterns declared on its exchange.

A message routed to zero queues is confirmed by RabbitMQ and then discarded, so an unmatched routing key is silent total message loss. On no match this resolves to a human-readable error-message string type, so the compile error explains the problem instead of collapsing to never — matching the MatchingBindingPattern convention.

Skipped (resolves to Key) when either side is non-literal, or when no patterns are declared: those cases cannot be decided at compile time and are left to the define-time check in defineContract.

Scope: single-hop queue bindings on topic and direct exchanges. Fanout, headers, and exchange-to-exchange forwards are deliberately not modelled here — deciding them needs graph traversal in the type system, which risks recursion-depth failures and false compile errors on valid contracts. Those cases fall through to the define-time check, which sees the whole graph.

Type Parameters ​

Type ParameterDescription
Key extends stringThe publisher's concrete routing key
Patterns extends stringUnion of binding patterns declared on the exchange

Example ​

typescript
type Ok = RoutableRoutingKey<"order.created", "order.#" | "user.#">; // "order.created"
type Bad = RoutableRoutingKey<"order.created", "user.#">;
// "Error: routing key 'order.created' matches none of the declared binding
//  patterns; the broker would confirm and discard every message"

RoutingKey ​

ts
type RoutingKey<S> = S extends "" ? never : S extends `${string}*${string}` | `${string}#${string}` ? never : S;

Defined in: builder/routing-types.ts:25

Type-safe routing key that validates basic format.

Validates that a routing key follows basic AMQP routing key rules:

  • Must not contain wildcards (* or #)
  • Must not be empty
  • Should contain alphanumeric characters, dots, hyphens, and underscores

Note: Full character-by-character validation is not performed to avoid TypeScript recursion depth limits. Runtime validation is still recommended.

Type Parameters ​

Type ParameterDescription
S extends stringThe routing key string to validate

Example ​

typescript
type Valid = RoutingKey<"order.created">; // "order.created"
type Invalid = RoutingKey<"order.*">; // never (contains wildcard)
type Invalid2 = RoutingKey<"">; // never (empty string)

RpcDefinition ​

ts
type RpcDefinition<TRequestMessage, TResponseMessage, TQueue, TErrors> = object;

Defined in: types.ts:1097

Definition of an RPC operation: a request/response pair flowing over a request queue with replies routed back via direct reply-to.

An RPC is bidirectional on both ends — the server consumes requests and publishes responses; the client publishes requests and consumes responses — so it has its own slot in the contract (rpcs) rather than being shoehorned into consumers or publishers.

See ​

defineRpc for creating RPC definitions

Type Parameters ​

Type ParameterDefault typeDescription
TRequestMessage extends MessageDefinitionMessageDefinitionThe request message definition
TResponseMessage extends MessageDefinitionMessageDefinitionThe response message definition
TQueue extends QueueDefinitionQueueDefinitionThe request queue entry
TErrors extends RpcErrorMap | undefinedRpcErrorMap | undefinedThe typed error map (undefined when the RPC declares none)

Properties ​

PropertyTypeDescriptionDefined in
errors?TErrorsTyped business errors the handler may return via Err(rpcError(code, data)). Error data is validated against the declared schema on the worker before the error reply is published, and re-validated on the client when it arrives. Business errors are replied and acked — never retried.types.ts:1115
queueTQueueThe queue that receives RPC requests. Replies are routed back via direct reply-to.types.ts:1104
requestTRequestMessageSchema for the request payload (validated on both publish and consume).types.ts:1106
responseTResponseMessageSchema for the response payload (validated on both worker reply and client receive).types.ts:1108

RpcErrorDefinition ​

ts
type RpcErrorDefinition<TData> = object;

Defined in: types.ts:1069

A single declared RPC error: the Standard Schema for its data payload, plus an optional default human-readable message.

The default message is used when the handler constructs the error without one (helpers.errors.CODE(data)) and as the client-side fallback when a reply arrives without a message on the wire.

See ​

defineRpc for declaring errors on an RPC

Type Parameters ​

Type ParameterDefault type
TData extends StandardSchemaV1StandardSchemaV1

Properties ​

PropertyTypeDescriptionDefined in
dataTDataSchema validating the error's data payload (worker before replying, client on receipt).types.ts:1071
message?stringDefault human-readable message when the handler does not supply one.types.ts:1073

RpcErrorMap ​

ts
type RpcErrorMap = Record<string, RpcErrorDefinition>;

Defined in: types.ts:1079

Typed error map for an RPC: error code → RpcErrorDefinition.


TopicExchangeDefinition ​

ts
type TopicExchangeDefinition<TName> = BaseExchangeDefinition<TName> & object;

Defined in: types.ts:473

A topic exchange definition.

Topic exchanges route messages to queues based on routing key patterns with wildcards:

  • * (star) matches exactly one word
  • # (hash) matches zero or more words

Words are separated by dots (e.g., order.created.high-value).

Type Parameters ​

Type ParameterDefault type
TName extends stringstring

Type Declaration ​

NameTypeDefined in
type"topic"types.ts:475

Example ​

typescript
const ordersExchange: TopicExchangeDefinition = defineExchange('orders', {
  type: 'topic', // This is the default type, so it can be omitted
});
// Can be bound with patterns like 'order.*' or 'order.#'

TtlBackoffInfrastructure ​

ts
type TtlBackoffInfrastructure = object;

Defined in: types.ts:748

TTL-backoff retry infrastructure derived from a queue definition.

This is computed (never stored on the contract) by deriveTtlBackoffInfrastructure: setupAmqpTopology declares the wait queues at channel-setup time, and the worker's retry pipeline publishes the retry copy to the tier queue matching the attempt's base delay. Each wait queue dead-letters back to the main queue via the default exchange.

Properties ​

PropertyTypeDescriptionDefined in
durablebooleanDurability shared by the wait queues (mirrors the main queue).types.ts:760
queueNamestringName of the main queue messages return to after the delay.types.ts:752
queueTypeQueueTypeQueue type shared by the wait queues (mirrors the main queue).types.ts:756
waitQueuesTtlBackoffWaitQueueDefinition[]One wait queue per distinct backoff delay, ascending by delayMs.types.ts:764

TtlBackoffRetryOptions ​

ts
type TtlBackoffRetryOptions = object;

Defined in: types.ts:51

TTL-Backoff retry options for exponential backoff with configurable delays.

Uses the TTL + wait queue pattern. Failed messages are published to a per-delay-tier wait queue with per-message TTL, then dead-lettered back to the main queue after the TTL expires. One wait queue per distinct backoff delay means a long-delay retry never blocks a short-delay retry; within a tier, head-of-line skew is bounded by the jitter spread (zero when jitter is disabled).

Benefits: Configurable delays with exponential backoff and jitter. Limitation: More topology (one wait queue per distinct delay).

Properties ​

PropertyTypeDescriptionDefined in
backoffMultiplier?numberExponential backoff multiplier. Default 2types.ts:76
initialDelayMs?numberInitial delay in ms before first retry. Default 1000types.ts:66
jitter?booleanAdd jitter to prevent thundering herd. Default truetypes.ts:81
maxDelayMs?numberMaximum delay in ms between retries. Default 30000types.ts:71
maxRetries?numberMaximum retry attempts before sending to DLQ. Minimum 1 - Must be a positive integer (1 or greater) Default 3types.ts:61
mode"ttl-backoff"TTL-Backoff mode uses wait queues with per-message TTL for exponential backoff.types.ts:55

TtlBackoffWaitQueueDefinition ​

ts
type TtlBackoffWaitQueueDefinition = object;

Defined in: types.ts:720

One derived TTL-backoff wait queue — a per-delay-tier holding queue.

Each distinct backoff delay in a queue's retry schedule gets its own wait queue so a long-delay retry can never block a short-delay retry behind it (RabbitMQ only dead-letters expired messages at the head of a queue).

Properties ​

PropertyTypeDescriptionDefined in
delayMsnumberThe tier's base backoff delay in ms (pre-jitter).types.ts:728
messageTtlMsnumberQueue-level x-message-ttl backstop. With jitter enabled this is the jitter ceiling (ceil(delayMs * 1.5)); without jitter it equals delayMs. The per-message expiration carries the actual (jittered) delay; this queue-level TTL bounds head-of-line skew within the tier to the jitter spread (zero when jitter is disabled).types.ts:736
namestringBroker name of the tier's wait queue: {queueName}-wait-{delayMs}ms.types.ts:724

Variables ​

deriveTtlBackoffInfrastructure ​

ts
const deriveTtlBackoffInfrastructure: (queue) => TtlBackoffInfrastructure | undefined = _deriveTtlBackoffInfrastructure;

Defined in: index.ts:36

Derive the TTL-backoff retry infrastructure for a queue: one wait queue per distinct backoff delay in the retry schedule.

The infrastructure is derived, not stored — defineQueue returns a plain QueueDefinition and the contract output contains only the queues you declared. setupAmqpTopology calls this helper at channel-setup time to declare the wait queues, and the worker's retry pipeline uses it to publish the retry copy to the tier queue matching the attempt's base delay.

How the retry hop works:

  1. The worker publishes the failed message to the tier's wait queue via the default exchange (routing key = wait queue name), with a per-message expiration carrying the (jittered) delay.
  2. The wait queue is declared with x-message-ttl set to the tier's jitter ceiling as a backstop, and dead-letters to the default exchange with x-dead-letter-routing-key set to the main queue name.
  3. When the TTL expires, RabbitMQ routes the message straight back to the main queue.

Because every message in a tier shares the same base delay, a long-delay retry can never block a short-delay retry: head-of-line skew within a tier is bounded by the jitter spread (at most delayMs), and is zero when jitter is disabled.

Parameters ​

ParameterTypeDescription
queueQueueDefinitionThe main queue definition

Returns ​

TtlBackoffInfrastructure | undefined

The derived infrastructure, or undefined when the queue's retry mode is not ttl-backoff

Example ​

typescript
const queue = defineQueue('order-processing', {
  retry: { mode: 'ttl-backoff', maxRetries: 3, initialDelayMs: 1000 },
});
const infra = deriveTtlBackoffInfrastructure(queue);
// infra.waitQueues → [
//   { name: 'order-processing-wait-1000ms', delayMs: 1000, messageTtlMs: 1500 },
//   { name: 'order-processing-wait-2000ms', delayMs: 2000, messageTtlMs: 3000 },
//   { name: 'order-processing-wait-4000ms', delayMs: 4000, messageTtlMs: 6000 },
// ]

Deprecated ​

Import from "@amqp-contract/contract/internal" — an internal helper with no semver guarantee.


extractConsumer ​

ts
const extractConsumer: (entry) => ConsumerDefinition = _extractConsumer;

Defined in: index.ts:38

Extract the ConsumerDefinition from any ConsumerEntry type.

Handles the following entry types:

  • ConsumerDefinition: returned as-is
  • EventConsumerResult: returns the nested .consumer property
  • CommandConsumerConfig: returns the nested .consumer property

Use this function when you need to access the underlying ConsumerDefinition from a consumer entry that may have been created with defineEventConsumer or defineCommandConsumer.

Parameters ​

ParameterTypeDescription
entryConsumerEntryThe consumer entry to extract from

Returns ​

ConsumerDefinition

The underlying ConsumerDefinition

Example ​

typescript
// Works with plain ConsumerDefinition
const consumer1 = defineConsumer(queue, message);
extractConsumer(consumer1).queue.name; // "my-queue"

// Works with EventConsumerResult
const consumer2 = defineEventConsumer(eventPublisher, queue);
extractConsumer(consumer2).queue.name; // "my-queue"

// Works with CommandConsumerConfig
const consumer3 = defineCommandConsumer(queue, exchange, message, { routingKey: "cmd" });
extractConsumer(consumer3).queue.name; // "my-queue"

Deprecated ​

Import from "@amqp-contract/contract/internal" — an internal helper with no semver guarantee.


isBridgedPublisherConfig ​

ts
const isBridgedPublisherConfig: (value) => value is BridgedPublisherConfig<MessageDefinition, ExchangeDefinition, ExchangeDefinition> = _isBridgedPublisherConfig;

Defined in: index.ts:40

Type guard to check if a value is a BridgedPublisherConfig.

Parameters ​

ParameterTypeDescription
valueunknownThe value to check

Returns ​

value is BridgedPublisherConfig<MessageDefinition, ExchangeDefinition, ExchangeDefinition>

True if the value is a BridgedPublisherConfig

Deprecated ​

Import from "@amqp-contract/contract/internal" — an internal helper with no semver guarantee.


isCommandConsumerConfig ​

ts
const isCommandConsumerConfig: (value) => value is CommandConsumerConfig<MessageDefinition, ExchangeDefinition, string | undefined, QueueDefinition> = _isCommandConsumerConfig;

Defined in: index.ts:42

Type guard to check if a value is a CommandConsumerConfig.

Parameters ​

ParameterTypeDescription
valueunknownThe value to check

Returns ​

value is CommandConsumerConfig<MessageDefinition, ExchangeDefinition, string | undefined, QueueDefinition>

True if the value is a CommandConsumerConfig

Deprecated ​

Import from "@amqp-contract/contract/internal" — an internal helper with no semver guarantee.


isEventConsumerResult ​

ts
const isEventConsumerResult: (value) => value is EventConsumerResult<MessageDefinition, ExchangeDefinition, QueueDefinition, ExchangeBindingDefinition | undefined, ExchangeDefinition | undefined> = _isEventConsumerResult;

Defined in: index.ts:44

Type guard to check if a value is an EventConsumerResult.

Parameters ​

ParameterTypeDescription
valueunknownThe value to check

Returns ​

value is EventConsumerResult<MessageDefinition, ExchangeDefinition, QueueDefinition, ExchangeBindingDefinition | undefined, ExchangeDefinition | undefined>

True if the value is an EventConsumerResult

Deprecated ​

Import from "@amqp-contract/contract/internal" — an internal helper with no semver guarantee.


isEventPublisherConfig ​

ts
const isEventPublisherConfig: (value) => value is EventPublisherConfig<MessageDefinition, ExchangeDefinition, string | undefined> = _isEventPublisherConfig;

Defined in: index.ts:46

Type guard to check if a value is an EventPublisherConfig.

Parameters ​

ParameterTypeDescription
valueunknownThe value to check

Returns ​

value is EventPublisherConfig<MessageDefinition, ExchangeDefinition, string | undefined>

True if the value is an EventPublisherConfig

Deprecated ​

Import from "@amqp-contract/contract/internal" — an internal helper with no semver guarantee.


ttlBackoffBaseDelay ​

ts
const ttlBackoffBaseDelay: (retry, retryCount) => number = _ttlBackoffBaseDelay;

Defined in: index.ts:48

Base (pre-jitter) backoff delay for a given retry attempt: min(initialDelayMs * backoffMultiplier ^ retryCount, maxDelayMs).

retryCount is zero-based — the delay applied before retry attempt retryCount + 1.

Parameters ​

ParameterTypeDescription
retryResolvedTtlBackoffRetryOptionsResolved TTL-backoff retry options
retryCountnumberNumber of retries already attempted (0 for the first retry)

Returns ​

number

The base delay in milliseconds

Deprecated ​

Import from "@amqp-contract/contract/internal" — an internal helper with no semver guarantee.


ttlBackoffWaitQueueName ​

ts
const ttlBackoffWaitQueueName: (queueName, delayMs) => string = _ttlBackoffWaitQueueName;

Defined in: index.ts:50

Broker name of the wait queue for a delay tier: {queueName}-wait-{delayMs}ms.

Parameters ​

ParameterTypeDescription
queueNamestringThe main queue name
delayMsnumberThe tier's base delay in milliseconds

Returns ​

string

The wait queue name

Deprecated ​

Import from "@amqp-contract/contract/internal" — an internal helper with no semver guarantee.

Functions ​

defineCommandConsumer() ​

ts
function defineCommandConsumer<TMessage, TQueueDefinition, TExchange, TRoutingKey>(
   queue, 
   exchange, 
   message, 
   ...options
): CommandConsumerConfig<TMessage, TExchange, [TExchange] extends [KeylessExchange] ? undefined : TRoutingKey, TQueueDefinition>;

Defined in: builder/command.ts:139

Define a command consumer.

Commands are sent by publishers to a specific queue. The consumer "owns" the queue and defines what commands it accepts; publishers are derived from it with defineCommandPublisher.

The exchange type decides the options:

  • fanout / headers: no routing key. options is optional.
  • direct: routingKey is required and concrete (matched exactly).
  • topic: routingKey is required and may be a pattern (* one word, # zero or more); publishers then send concrete keys matching it.

Type Parameters ​

Type ParameterDefault type
TMessage extends MessageDefinition-
TQueueDefinition extends QueueDefinition-
TExchange extends ExchangeDefinition-
TRoutingKey extends stringnever

Parameters ​

ParameterTypeDescription
queueTQueueDefinitionThe queue that will receive commands
exchangeTExchangeThe exchange that routes commands
messageTMessageThe message definition (schema and metadata)
...optionsCommandConsumerOptionsArgs<TExchange, TRoutingKey>Binding configuration (required for direct and topic exchanges)

Returns ​

CommandConsumerConfig<TMessage, TExchange, [TExchange] extends [KeylessExchange] ? undefined : TRoutingKey, TQueueDefinition>

A command consumer configuration

Example ​

typescript
// Keyless exchange
const tasksExchange = defineExchange('tasks', { type: 'fanout' });
const taskMessage = defineMessage(z.object({ taskId: z.string() }));
const executeTask = defineCommandConsumer(taskQueue, tasksExchange, taskMessage);
const sendTask = defineCommandPublisher(executeTask);

// Topic exchange: the consumer binds a pattern, publishers send concrete keys
const ordersExchange = defineExchange('orders', { type: 'topic' });
const orderMessage = defineMessage(z.object({ orderId: z.string() }));
const processOrder = defineCommandConsumer(orderQueue, ordersExchange, orderMessage, {
  routingKey: 'order.*',
});
const createOrder = defineCommandPublisher(processOrder, {
  routingKey: 'order.create',
});

defineCommandPublisher() ​

ts
function defineCommandPublisher<TMessage, TExchange, TRoutingKey, TBridgeExchange, TPublisherRoutingKey>(commandConsumer, options?): [NoInfer<TBridgeExchange>] extends [never] ? CommandPublisherResult<TMessage, TExchange, TPublisherRoutingKey> : BridgedPublisherConfig<TMessage, NoInfer<TBridgeExchange>, TExchange>;

Defined in: builder/command.ts:277

Create a publisher that sends commands to a command consumer.

The publisher targets the consumer's exchange with the consumer's routing key. On a topic exchange, routingKey may override it with a concrete key — typically one matching the consumer's binding pattern.

When bridgeExchange is provided, the publisher publishes to the bridge (local domain) exchange instead, and an exchange-to-exchange binding is created from the bridge to the target. The bridge must preserve the target's routing semantics: fanout↔fanout, headers↔headers, and direct/topic↔direct/topic.

Type Parameters ​

Type ParameterDefault type
TMessage extends MessageDefinition-
TExchange extends ExchangeDefinition-
TRoutingKey extends string | undefined-
TBridgeExchange extends | FanoutExchangeDefinition | HeadersExchangeDefinition | DirectExchangeDefinition | TopicExchangeDefinitionnever
TPublisherRoutingKey extends stringTRoutingKey & string

Parameters ​

ParameterTypeDescription
commandConsumerCommandConsumerConfig<TMessage, TExchange, TRoutingKey>The command consumer configuration
options?CommandPublisherOptions<TExchange, TBridgeExchange, TPublisherRoutingKey>Optional publisher configuration

Returns ​

[NoInfer<TBridgeExchange>] extends [never] ? CommandPublisherResult<TMessage, TExchange, TPublisherRoutingKey> : BridgedPublisherConfig<TMessage, NoInfer<TBridgeExchange>, TExchange>

A publisher definition, or a bridged publisher configuration when bridgeExchange is set

Example ​

typescript
// Consumer binds with pattern
const processOrder = defineCommandConsumer(orderQueue, topicExchange, orderMessage, {
  routingKey: 'order.*',
});

// Publisher uses concrete key matching the pattern
const createOrder = defineCommandPublisher(processOrder, {
  routingKey: 'order.create',
});

// Keyless exchange
const executeTask = defineCommandConsumer(taskQueue, fanoutExchange, taskMessage);
const sendTask = defineCommandPublisher(executeTask);

defineConsumer() ​

ts
function defineConsumer<TMessage>(
   queue, 
   message, 
   options?
): ConsumerDefinition<TMessage>;

Defined in: builder/consumer.ts:123

Define a message consumer.

A consumer receives and processes messages from a queue. The message schema is validated automatically when messages are consumed, ensuring type safety for your handlers.

Consumers are associated with a specific queue and message type. When you create a worker with this consumer, it will process messages from the queue according to the schema.

Which pattern to use:

PatternBest forDescription
definePublisher + defineConsumerIndependent definitionDefine publishers and consumers separately with manual schema consistency
defineEventPublisher + defineEventConsumerEvent broadcastingDefine event publisher first, create consumers that subscribe to it
defineCommandConsumer + defineCommandPublisherTask queuesDefine command consumer first, create publishers that send commands to it

Use defineCommandConsumer when:

  • One consumer receives from multiple publishers
  • You want automatic schema consistency between consumer and publishers
  • You're building task queue or command patterns

Type Parameters ​

Type Parameter
TMessage extends MessageDefinition

Parameters ​

ParameterTypeDescription
queueQueueDefinitionThe queue definition to consume from
messageTMessageThe message definition with payload schema
options?Omit<ConsumerDefinition<TMessage>, "queue" | "message">Optional consumer configuration

Returns ​

ConsumerDefinition<TMessage>

A consumer definition with inferred message types

Example ​

typescript
import { z } from 'zod';

const orderQueue = defineQueue('order-processing');
const orderMessage = defineMessage(
  z.object({
    orderId: z.string().uuid(),
    customerId: z.string().uuid(),
    amount: z.number().positive(),
  })
);

const processOrderConsumer = defineConsumer(orderQueue, orderMessage);

// Later, when creating a worker, you'll provide a handler for this consumer.
// Handlers return AsyncResult<void, HandlerError> (from unthrown):
// const worker = await TypedAmqpWorker.create({
//   contract,
//   handlers: {
//     processOrder: ({ input: { payload } }) => {
//       // payload is automatically typed based on the schema
//       console.log(payload.orderId); // string
//       return OkAsync();
//     },
//   },
//   urls: ['amqp://localhost'],
// }).getOrThrow();

See ​

  • defineCommandConsumer - For task queue patterns with automatic schema consistency
  • defineEventPublisher - For event-driven patterns with automatic schema consistency

defineContract() ​

ts
function defineContract<TContract>(definition): ContractOutput<TContract>;

Defined in: builder/contract.ts:138

Define an AMQP contract.

A contract is the central definition of your AMQP messaging topology. It brings together publishers and consumers in a single, type-safe definition. Exchanges, queues, and bindings are automatically extracted from publishers and consumers.

The contract is used by both clients (for publishing) and workers (for consuming) to ensure type safety throughout your messaging infrastructure. TypeScript will infer all message types and publisher/consumer names from the contract.

Type Parameters ​

Type Parameter
TContract extends ContractDefinitionInput

Parameters ​

ParameterTypeDescription
definitionTContractThe contract definition containing publishers and consumers

Returns ​

ContractOutput<TContract>

The contract definition with fully inferred exchanges, queues, bindings, publishers, and consumers

Example ​

typescript
import {
  defineContract,
  defineExchange,
  defineQueue,
  defineEventPublisher,
  defineEventConsumer,
  defineMessage,
} from '@amqp-contract/contract';
import { z } from 'zod';

// Define resources
const ordersExchange = defineExchange('orders');
const dlx = defineExchange('orders-dlx', { type: 'direct' });
const orderQueue = defineQueue('order-processing', {
  deadLetter: { exchange: dlx },
  retry: { mode: 'immediate-requeue', maxRetries: 3 },
});
const orderMessage = defineMessage(
  z.object({
    orderId: z.string(),
    amount: z.number(),
  })
);

// Define event publisher
const orderCreatedEvent = defineEventPublisher(ordersExchange, orderMessage, {
  routingKey: 'order.created',
});

// Compose contract - exchanges, queues, bindings are auto-extracted
export const contract = defineContract({
  publishers: {
    orderCreated: orderCreatedEvent,
  },
  consumers: {
    processOrder: defineEventConsumer(orderCreatedEvent, orderQueue),
  },
});

// TypeScript now knows:
// - contract.exchanges.orders, contract.exchanges['orders-dlx']
// - contract.queues['order-processing']
// - contract.bindings.processOrderBinding
// - client.publish('orderCreated', { orderId: string, amount: number })
// - handler: ({ input: { payload }: { payload: { orderId: string, amount: number } } }) => AsyncResult<void, HandlerError>

defineContractBinding() ​

ts
function defineContractBinding<C, B>(contract, binding): BoundContract<C, B>;

Defined in: contract-binding.ts:82

Materialize explicitly mapped deployment resources without changing message schemas or logical operation keys. Unmapped shared producer resources stay put. Queue names also determine RPC destinations and derived TTL-backoff resources.

Type Parameters ​

Type Parameter
C extends ContractDefinition
B extends ContractBinding

Parameters ​

ParameterType
contractC
bindingB

Returns ​

BoundContract<C, B>


defineDeadLetterQueue() ​

ts
function defineDeadLetterQueue<TName, TExchange>(
   deadLetterExchange, 
   name, 
   ...options
): DeadLetterQueue<TName>;

Defined in: builder/dead-letter-queue.ts:76

Define a dead-letter queue bound to a dead-letter exchange.

Collapses the usual pair — defineQueue(name) plus defineQueueBinding(queue, dlx, { routingKey }) — into one call, and picks the binding key that actually receives dead letters: # on a topic exchange, none on fanout / headers, and a required explicit key on a direct exchange (where # would be a literal key that matches nothing).

The result is ordinary topology: add queue and binding to the contract and defineContract validates them exactly as if they had been written out — including the dead-letter routability check on every queue that dead-letters to this exchange.

Type Parameters ​

Type Parameter
TName extends string
TExchange extends ExchangeDefinition

Parameters ​

ParameterTypeDescription
deadLetterExchangeTExchangeThe exchange queues dead-letter to (their deadLetter.exchange)
nameTNameThe dead-letter queue's name
...optionsDeadLetterQueueOptionsArgs<TExchange>Required for a direct exchange

Returns ​

DeadLetterQueue<TName>

The dead-letter queue and its binding

Example ​

typescript
const ordersDlx = defineExchange('orders-dlx');
const orderQueue = defineQueue('order-processing', { deadLetter: { exchange: ordersDlx } });
const ordersDlq = defineDeadLetterQueue(ordersDlx, 'orders-dlq');

const contract = defineContract({
  consumers: { processOrder: defineEventConsumer(orderCreatedEvent, orderQueue) },
  queues: { ordersDlq: ordersDlq.queue },
  bindings: { ordersDlq: ordersDlq.binding },
});

defineEventConsumer() ​

ts
function defineEventConsumer<TMessage, TExchange, TRoutingKey, TQueueDefinition, TBridgeExchange, TConsumerRoutingKey>(
   eventPublisher, 
   queue, 
   options?
): [NoInfer<TBridgeExchange>] extends [never] ? EventConsumerResult<TMessage, TExchange, TQueueDefinition, ExchangeBindingDefinition | undefined, ExchangeDefinition | undefined> : EventConsumerResult<TMessage, TExchange, TQueueDefinition, ExchangeBindingDefinition, NoInfer<TBridgeExchange>>;

Defined in: builder/event.ts:333

Create a consumer that subscribes to an event.

The consumer's queue is bound to the event's exchange with the publisher's routing key. The source exchange type decides the options:

  • fanout / headers: no routing key.
  • direct: the publisher's key, which cannot be overridden.
  • topic: routingKey may override the publisher's key with a pattern (* one word, # zero or more). A pattern that can never match the publisher's concrete key — e.g. user.* against order.created — is a compile-time error, because the binding would silently receive nothing.

When bridgeExchange is provided, the queue binds to the bridge exchange instead of the source exchange, and an exchange-to-exchange binding is created from the source to the bridge. The bridge must preserve the source's routing semantics: fanout↔fanout, headers↔headers, and direct/topic↔direct/topic.

Type Parameters ​

Type ParameterDefault type
TMessage extends MessageDefinition-
TExchange extends ExchangeDefinition-
TRoutingKey extends string | undefined-
TQueueDefinition extends QueueDefinition-
TBridgeExchange extends | FanoutExchangeDefinition | HeadersExchangeDefinition | KeyedExchangenever
TConsumerRoutingKey extends stringTRoutingKey & string

Parameters ​

ParameterTypeDescription
eventPublisherEventPublisherConfig<TMessage, TExchange, TRoutingKey>The event publisher configuration
queueTQueueDefinitionThe queue that will receive messages
options?EventConsumerOptions<TExchange, TRoutingKey, TBridgeExchange, TConsumerRoutingKey>Optional binding configuration

Returns ​

[NoInfer<TBridgeExchange>] extends [never] ? EventConsumerResult<TMessage, TExchange, TQueueDefinition, ExchangeBindingDefinition | undefined, ExchangeDefinition | undefined> : EventConsumerResult<TMessage, TExchange, TQueueDefinition, ExchangeBindingDefinition, NoInfer<TBridgeExchange>>

An object with the consumer definition and binding (plus the exchange-to-exchange binding and bridge exchange when bridging)

Example ​

typescript
const orderCreatedEvent = defineEventPublisher(ordersExchange, orderMessage, {
  routingKey: 'order.created',
});

// Use exact routing key from publisher
const { consumer: exactConsumer } = defineEventConsumer(orderCreatedEvent, exactQueue);

// Override with pattern to receive all order events
const { consumer: allConsumer } = defineEventConsumer(orderCreatedEvent, allQueue, {
  routingKey: 'order.*',
});

// A pattern that can never match the publisher's key fails to compile:
// defineEventConsumer(orderCreatedEvent, allQueue, { routingKey: 'user.*' });
// Error: binding pattern 'user.*' can never match the publisher routing key 'order.created'

// Keyless exchange
const logEvent = defineEventPublisher(logsExchange, logMessage);
const { consumer, binding } = defineEventConsumer(logEvent, logsQueue);

defineEventPublisher() ​

ts
function defineEventPublisher<TMessage, TExchange, TRoutingKey>(
   exchange, 
   message, 
   ...options
): EventPublisherConfig<TMessage, TExchange, [TExchange] extends [KeylessExchange] ? undefined : TRoutingKey>;

Defined in: builder/event.ts:192

Define an event publisher.

Events are published without knowing who consumes them. Multiple consumers can subscribe to the same event using defineEventConsumer.

The exchange type decides the options:

  • fanout / headers: no routing key — fanout broadcasts to every bound queue, headers routes on header values. options is optional.
  • direct: routingKey is required; consumers receive messages whose key matches it exactly.
  • topic: routingKey is required and concrete (no wildcards); consumers can subscribe with * / # patterns via defineEventConsumer.

Type Parameters ​

Type ParameterDefault type
TMessage extends MessageDefinition-
TExchange extends ExchangeDefinition-
TRoutingKey extends stringnever

Parameters ​

ParameterTypeDescription
exchangeTExchangeThe exchange to publish to
messageTMessageThe message definition (schema and metadata)
...optionsEventPublisherOptionsArgs<TExchange, TRoutingKey>Publisher configuration (required for direct and topic exchanges)

Returns ​

EventPublisherConfig<TMessage, TExchange, [TExchange] extends [KeylessExchange] ? undefined : TRoutingKey>

An event publisher configuration

Example ​

typescript
// Keyless exchange: no routing key
const logsExchange = defineExchange('logs', { type: 'fanout' });
const logMessage = defineMessage(z.object({
  level: z.enum(['info', 'warn', 'error']),
  message: z.string(),
}));
const logEvent = defineEventPublisher(logsExchange, logMessage);

// Direct exchange: exact routing key
const tasksExchange = defineExchange('tasks', { type: 'direct' });
const taskMessage = defineMessage(z.object({ taskId: z.string() }));
const taskEvent = defineEventPublisher(tasksExchange, taskMessage, {
  routingKey: 'task.execute',
});

// Topic exchange: concrete key; consumers may bind with patterns
const ordersExchange = defineExchange('orders', { type: 'topic' });
const orderMessage = defineMessage(z.object({
  orderId: z.string(),
  amount: z.number(),
}));
const orderCreatedEvent = defineEventPublisher(ordersExchange, orderMessage, {
  routingKey: 'order.created',
});
const { consumer, binding } = defineEventConsumer(
  orderCreatedEvent,
  allOrdersQueue,
  { routingKey: 'order.*' },
);

defineExchange() ​

ts
function defineExchange<TName, TType>(name, options?): 
  | Extract<TopicExchangeDefinition<TName>, {
  type: TType;
}>
  | Extract<DirectExchangeDefinition<TName>, {
  type: TType;
}>
  | Extract<FanoutExchangeDefinition<TName>, {
  type: TType;
}>
  | Extract<HeadersExchangeDefinition<TName>, {
  type: TType;
}>;

Defined in: builder/exchange.ts:39

Define an AMQP exchange.

The type selects the routing behaviour, and the return type narrows to match it — defineExchange('tasks', { type: 'direct' }) is a DirectExchangeDefinition<'tasks'>, so the builders that require a specific exchange kind (a direct/topic publisher's routing key, a fanout event's bridge) accept or reject it at compile time.

  • topic (the default) routes on routing-key patterns: * matches one word, # matches zero or more, words separated by dots.
  • direct routes on an exact routing-key match — point-to-point.
  • fanout broadcasts to every bound queue, ignoring the routing key.
  • headers routes on header values rather than the routing key.

Type Parameters ​

Type ParameterDefault type
TName extends string-
TType extends "fanout" | "headers" | "topic" | "direct""topic"

Parameters ​

ParameterTypeDescription
nameTNameThe name of the exchange
options?object & Omit<BaseExchangeDefinition, "type" | "name">Optional exchange configuration

Returns ​

| Extract<TopicExchangeDefinition<TName>, { type: TType; }> | Extract<DirectExchangeDefinition<TName>, { type: TType; }> | Extract<FanoutExchangeDefinition<TName>, { type: TType; }> | Extract<HeadersExchangeDefinition<TName>, { type: TType; }>

An exchange definition narrowed to the requested type

Example ​

typescript
const ordersExchange = defineExchange('orders'); // topic — the default
const tasksExchange = defineExchange('tasks', { type: 'direct' });
const logsExchange = defineExchange('logs', { type: 'fanout' });
const routesExchange = defineExchange('routes', { type: 'headers' });

defineExchangeBinding() ​

Call Signature ​

ts
function defineExchangeBinding(
   destination, 
   source, 
   options?
): object & object;

Defined in: builder/binding.ts:184

Define a binding between two exchanges (exchange-to-exchange routing).

Binds a destination exchange to a fanout or headers source exchange. Messages published to the source exchange will be forwarded to the destination exchange. Fanout and headers exchanges ignore routing keys, so this overload doesn't require one.

Parameters ​
ParameterTypeDescription
destinationExchangeDefinitionThe destination exchange definition
source| FanoutExchangeDefinition | HeadersExchangeDefinitionThe fanout or headers source exchange definition
options?Omit<object & object, "type" | "source" | "destination" | "routingKey">Optional binding configuration
Returns ​

object & object

An exchange binding definition

Example ​
typescript
const sourceExchange = defineExchange('logs', { type: 'fanout' });
const destExchange = defineExchange('all-logs', { type: 'fanout' });

const binding = defineExchangeBinding(destExchange, sourceExchange);

Call Signature ​

ts
function defineExchangeBinding(
   destination, 
   source, 
   options
): object & object;

Defined in: builder/binding.ts:224

Define a binding between two exchanges (exchange-to-exchange routing).

Binds a destination exchange to a direct or topic source exchange with a routing key pattern. Messages are forwarded from source to destination only if the routing key matches the pattern. On a direct source a * or # segment is rejected: it would be matched literally.

Parameters ​
ParameterTypeDescription
destinationExchangeDefinitionThe destination exchange definition
source| DirectExchangeDefinition | TopicExchangeDefinitionThe direct or topic source exchange definition
optionsOmit<Extract<ExchangeBindingDefinition, { source: | DirectExchangeDefinition | TopicExchangeDefinition; }>, "type" | "source" | "destination">Binding configuration (routingKey is required)
Returns ​

object & object

An exchange binding definition

Example ​
typescript
const ordersExchange = defineExchange('orders');
const importantExchange = defineExchange('important-orders');

// Forward only high-value orders
const binding = defineExchangeBinding(importantExchange, ordersExchange, {
  routingKey: 'order.high-value.*'
});

defineMessage() ​

ts
function defineMessage<TPayload, THeaders>(payload, options?): MessageDefinition<TPayload, THeaders>;

Defined in: builder/message.ts:41

Define a message definition with payload and optional headers/metadata.

A message definition specifies the schema for message payloads and headers using Standard Schema v1 compatible libraries (Zod, Valibot, ArkType, etc.). The schemas are used for automatic validation when publishing or consuming messages.

Type Parameters ​

Type ParameterDefault type
TPayload extends AnySchema-
THeaders extends | StandardSchemaV1<Record<string, unknown>, Record<string, unknown>> | undefinedundefined

Parameters ​

ParameterTypeDescription
payloadTPayloadThe payload schema (must be Standard Schema v1 compatible)
options?{ description?: string; headers?: THeaders; summary?: string; }Optional message metadata
options.description?stringDetailed description for documentation (used in AsyncAPI generation)
options.headers?THeadersOptional header schema for message headers
options.summary?stringBrief description for documentation (used in AsyncAPI generation)

Returns ​

MessageDefinition<TPayload, THeaders>

A message definition with inferred types

Example ​

typescript
import { z } from 'zod';

const orderMessage = defineMessage(
  z.object({
    orderId: z.string().uuid(),
    customerId: z.string().uuid(),
    amount: z.number().positive(),
    items: z.array(z.object({
      productId: z.string(),
      quantity: z.number().int().positive(),
    })),
  }),
  {
    summary: 'Order created event',
    description: 'Emitted when a new order is created in the system'
  }
);

definePublisher() ​

Call Signature ​

ts
function definePublisher<TMessage>(
   exchange, 
   message, 
   options?
): object & object;

Defined in: builder/publisher.ts:58

Define a message publisher for a fanout or headers exchange.

A publisher sends messages to an exchange. For fanout exchanges, messages are broadcast to all bound queues regardless of routing key, so no routing key is required. For headers exchanges, routing is based on message headers rather than routing keys, so no routing key is required either.

The message schema is validated when publishing to ensure type safety.

Which pattern to use:

PatternBest forDescription
definePublisher + defineConsumerIndependent definitionDefine publishers and consumers separately with manual schema consistency
defineEventPublisher + defineEventConsumerEvent broadcastingDefine event publisher first, create consumers that subscribe to it
defineCommandConsumer + defineCommandPublisherTask queuesDefine command consumer first, create publishers that send commands to it

Use defineEventPublisher when:

  • One publisher feeds multiple consumers
  • You want automatic schema consistency between publisher and consumers
  • You're building event-driven architectures
Type Parameters ​
Type Parameter
TMessage extends MessageDefinition
Parameters ​
ParameterTypeDescription
exchange| FanoutExchangeDefinition | HeadersExchangeDefinitionThe fanout or headers exchange definition to publish to
messageTMessageThe message definition with payload schema
options?Omit<object & object, "message" | "routingKey" | "exchange">Optional publisher configuration
Returns ​

object & object

A publisher definition with inferred message types

Example ​
typescript
import { z } from 'zod';

const logsExchange = defineExchange('logs', { type: 'fanout' });
const logMessage = defineMessage(
  z.object({
    level: z.enum(['info', 'warn', 'error']),
    message: z.string(),
    timestamp: z.string().datetime(),
  })
);

const logPublisher = definePublisher(logsExchange, logMessage);
See ​
  • defineEventPublisher - For event-driven patterns with automatic schema consistency
  • defineCommandConsumer - For task queue patterns with automatic schema consistency

Call Signature ​

ts
function definePublisher<TMessage>(
   exchange, 
   message, 
   options
): object & object;

Defined in: builder/publisher.ts:124

Define a message publisher for a direct or topic exchange.

A publisher sends messages to an exchange with a specific routing key. The routing key determines which queues receive the message.

The message schema is validated when publishing to ensure type safety.

Which pattern to use:

PatternBest forDescription
definePublisher + defineConsumerIndependent definitionDefine publishers and consumers separately with manual schema consistency
defineEventPublisher + defineEventConsumerEvent broadcastingDefine event publisher first, create consumers that subscribe to it
defineCommandConsumer + defineCommandPublisherTask queuesDefine command consumer first, create publishers that send commands to it

Use defineEventPublisher when:

  • One publisher feeds multiple consumers
  • You want automatic schema consistency between publisher and consumers
  • You're building event-driven architectures
Type Parameters ​
Type Parameter
TMessage extends MessageDefinition
Parameters ​
ParameterTypeDescription
exchange| DirectExchangeDefinition | TopicExchangeDefinitionThe direct or topic exchange definition to publish to
messageTMessageThe message definition with payload schema
optionsOmit<Extract<PublisherDefinition<TMessage>, { exchange: | DirectExchangeDefinition | TopicExchangeDefinition; }>, "exchange" | "message">Publisher configuration (routingKey is required)
Returns ​

object & object

A publisher definition with inferred message types

Example ​
typescript
import { z } from 'zod';

const ordersExchange = defineExchange('orders');
const orderMessage = defineMessage(
  z.object({
    orderId: z.string().uuid(),
    amount: z.number().positive(),
  }),
  {
    summary: 'Order created event',
    description: 'Emitted when a new order is created'
  }
);

const orderCreatedPublisher = definePublisher(ordersExchange, orderMessage, {
  routingKey: 'order.created'
});
See ​
  • defineEventPublisher - For event-driven patterns with automatic schema consistency
  • defineCommandConsumer - For task queue patterns with automatic schema consistency

defineQueue() ​

Call Signature ​

ts
function defineQueue<TName, TDlx>(name, options): QueueDefinitionWithDeadLetterExchange<TName, TDlx>;

Defined in: builder/queue.ts:149

Define an AMQP queue.

A queue stores messages until they are consumed by workers. Queues can be bound to exchanges to receive messages based on routing rules.

By default, queues are created as quorum queues which provide better durability and high-availability. Use type: 'classic' for special cases like non-durable queues or x-max-priority priority levels.

Type Parameters ​
Type Parameter
TName extends string
TDlx extends ExchangeDefinition
Parameters ​
ParameterTypeDescription
nameTNameThe name of the queue
optionsDefineQueueOptionsWithDeadLetterExchange<TDlx>Optional queue configuration
Returns ​

QueueDefinitionWithDeadLetterExchange<TName, TDlx>

A queue definition

Example ​
typescript
// Quorum queue (default, recommended for production)
const orderQueue = defineQueue('order-processing');

// Explicit quorum queue with dead letter exchange
const dlx = defineExchange('orders-dlx');
const orderQueueWithDLX = defineQueue('order-processing', {
  type: 'quorum',
  deadLetter: {
    exchange: dlx,
    routingKey: 'order.failed'
  },
  arguments: {
    'x-message-ttl': 86400000, // 24 hours
  }
});

// Classic queue (for special cases)
const tempQueue = defineQueue('temp-queue', {
  type: 'classic',
  durable: false,
  autoDelete: true,
});

// Classic priority levels (x-max-priority). A quorum queue needs none of
// this: it honors the per-message `priority` natively on RabbitMQ 4.0+.
const taskQueue = defineQueue('urgent-tasks', {
  type: 'classic',
  maxPriority: 10,
});

// Queue with TTL-backoff retry (wait queues are derived at setup time)
const retryDlx = defineExchange('payments-dlx', { type: 'direct' });
const paymentQueue = defineQueue('payment-processing', {
  deadLetter: { exchange: retryDlx },
  retry: { mode: 'ttl-backoff', maxRetries: 5 },
});
// paymentQueue is a plain QueueDefinition; setupAmqpTopology declares the
// per-delay wait queues derived from its retry config

Call Signature ​

ts
function defineQueue<TName>(name, options?): QueueDefinition<TName>;

Defined in: builder/queue.ts:154

Define an AMQP queue.

A queue stores messages until they are consumed by workers. Queues can be bound to exchanges to receive messages based on routing rules.

By default, queues are created as quorum queues which provide better durability and high-availability. Use type: 'classic' for special cases like non-durable queues or x-max-priority priority levels.

Type Parameters ​
Type Parameter
TName extends string
Parameters ​
ParameterTypeDescription
nameTNameThe name of the queue
options?DefineQueueOptionsOptional queue configuration
Returns ​

QueueDefinition<TName>

A queue definition

Example ​
typescript
// Quorum queue (default, recommended for production)
const orderQueue = defineQueue('order-processing');

// Explicit quorum queue with dead letter exchange
const dlx = defineExchange('orders-dlx');
const orderQueueWithDLX = defineQueue('order-processing', {
  type: 'quorum',
  deadLetter: {
    exchange: dlx,
    routingKey: 'order.failed'
  },
  arguments: {
    'x-message-ttl': 86400000, // 24 hours
  }
});

// Classic queue (for special cases)
const tempQueue = defineQueue('temp-queue', {
  type: 'classic',
  durable: false,
  autoDelete: true,
});

// Classic priority levels (x-max-priority). A quorum queue needs none of
// this: it honors the per-message `priority` natively on RabbitMQ 4.0+.
const taskQueue = defineQueue('urgent-tasks', {
  type: 'classic',
  maxPriority: 10,
});

// Queue with TTL-backoff retry (wait queues are derived at setup time)
const retryDlx = defineExchange('payments-dlx', { type: 'direct' });
const paymentQueue = defineQueue('payment-processing', {
  deadLetter: { exchange: retryDlx },
  retry: { mode: 'ttl-backoff', maxRetries: 5 },
});
// paymentQueue is a plain QueueDefinition; setupAmqpTopology declares the
// per-delay wait queues derived from its retry config

defineQueueBinding() ​

Call Signature ​

ts
function defineQueueBinding(
   queue, 
   exchange, 
   options?
): object & object;

Defined in: builder/binding.ts:36

Define a binding between a queue and a fanout or headers exchange.

Binds a queue to a fanout or headers exchange (no routing key needed). Fanout and headers exchanges ignore routing keys, so this overload doesn't require one.

Parameters ​
ParameterTypeDescription
queueQueueDefinitionThe queue definition to bind
exchange| FanoutExchangeDefinition | HeadersExchangeDefinitionThe fanout or headers exchange definition
options?Omit<object & object, "type" | "queue" | "routingKey" | "exchange">Optional binding configuration
Returns ​

object & object

A queue binding definition

Example ​
typescript
const logsQueue = defineQueue('logs-queue');
const logsExchange = defineExchange('logs', { type: 'fanout' });

const binding = defineQueueBinding(logsQueue, logsExchange);

Call Signature ​

ts
function defineQueueBinding(
   queue, 
   exchange, 
   options
): object & object;

Defined in: builder/binding.ts:87

Define a binding between a queue and a direct or topic exchange.

Binds a queue to an exchange with a specific routing key pattern. Messages are only routed to the queue if the routing key matches the pattern.

For direct exchanges: The routing key must match exactly. A * or # segment is rejected — a direct exchange treats it as a literal key, so the binding would silently receive nothing. For topic exchanges: The routing key can include wildcards:

  • * matches exactly one word
  • # matches zero or more words
Parameters ​
ParameterTypeDescription
queueQueueDefinitionThe queue definition to bind
exchange| DirectExchangeDefinition | TopicExchangeDefinitionThe direct or topic exchange definition
optionsOmit<Extract<QueueBindingDefinition, { exchange: | DirectExchangeDefinition | TopicExchangeDefinition; }>, "type" | "queue" | "exchange">Binding configuration (routingKey is required)
Returns ​

object & object

A queue binding definition

Example ​
typescript
const orderQueue = defineQueue('order-processing');
const ordersExchange = defineExchange('orders');

// Bind with exact routing key
const binding = defineQueueBinding(orderQueue, ordersExchange, {
  routingKey: 'order.created'
});

// Bind with wildcard pattern
const allOrdersBinding = defineQueueBinding(orderQueue, ordersExchange, {
  routingKey: 'order.*'  // Matches order.created, order.updated, etc.
});

defineRpc() ​

ts
function defineRpc<TRequestMessage, TResponseMessage, TQueue, TErrors>(queue, messages): RpcDefinition<TRequestMessage, TResponseMessage, TQueue, TErrors>;

Defined in: builder/rpc.ts:58

Define an RPC operation: a request/response pair flowing over a request queue with replies routed back via RabbitMQ direct reply-to.

RPC is bidirectional on both ends — the worker handler consumes the request and produces the response; client.call(name, request, options) publishes the request and awaits the typed response. Both sides share the same definition, so request and response schemas cannot drift between them.

Plug the result into defineContract({ rpcs: { name: ... } }). RPCs do not appear in publishers or consumers.

Type Parameters ​

Type ParameterDefault type
TRequestMessage extends MessageDefinition-
TResponseMessage extends MessageDefinition-
TQueue extends QueueDefinition-
TErrors extends RpcErrorMap | undefinedundefined

Parameters ​

ParameterTypeDescription
queueTQueueThe queue that receives RPC requests. The queue name is used as the routing key on the AMQP default direct exchange.
messages{ errors?: TErrors; request: TRequestMessage; response: TResponseMessage; }-
messages.errors?TErrorsOptional typed error map: error code → { data, message? }, where data is the Standard Schema for the error's payload and message an optional default human-readable message. Declared errors widen the handler's Err channel (return Err(rpcError(code, data))) and the client's call() error union; error data is schema-validated on both sides. Business errors are replied and acked — never retried.
messages.requestTRequestMessageSchema validated against incoming request payloads (server side) and outgoing requests (client side).
messages.responseTResponseMessageSchema validated against handler return values (server side) and incoming replies (client side).

Returns ​

RpcDefinition<TRequestMessage, TResponseMessage, TQueue, TErrors>

Example ​

typescript
import { defineQueue, defineMessage, defineRpc, defineContract } from '@amqp-contract/contract';
import { z } from 'zod';

const getOrder = defineRpc(defineQueue('rpc.get-order'), {
  request: defineMessage(z.object({ orderId: z.string() })),
  response: defineMessage(z.object({ orderId: z.string(), status: z.string() })),
  errors: {
    ORDER_NOT_FOUND: { data: z.object({ orderId: z.string() }), message: 'Order not found' },
  },
});

const contract = defineContract({ rpcs: { getOrder } });

// Server (worker): return the response, or a declared typed error
//   handlers: {
//     getOrder: ({ input: { payload } }) =>
//       orders.has(payload.orderId)
//         ? OkAsync(orders.get(payload.orderId))
//         : ErrAsync(rpcError('ORDER_NOT_FOUND', { orderId: payload.orderId })),
//   }

// Client: typed call — the error union includes RpcError<'ORDER_NOT_FOUND', { orderId: string }>
//   const result = await client.call('getOrder', { orderId: '42' }, { timeoutMs: 5_000 });
//   if (result.isErr() && isRpcError(result.error)) console.log(result.error.code);

formatIssue() ​

ts
function formatIssue(issue): string;

Defined in: issues.ts:11

Render a single Standard Schema issue as path.to.field: message (or just the message for root-level issues). Path segments may be raw property keys or { key } objects per the Standard Schema spec; both are handled.

Single source of truth for issue rendering across the client and worker — mirrors temporal-contract's shared formatter (org DNA).

Parameters ​

ParameterType
issueIssue

Returns ​

string


summarizeIssues() ​

ts
function summarizeIssues(issues, limit?): string;

Defined in: issues.ts:28

Render a list of Standard Schema issues as a single human-readable line: the first limit issues joined with ; , plus a (+N more) suffix when truncated. Empty input renders as "no issues" (defensive — validation failures always carry at least one issue).

Parameters ​

ParameterTypeDefault value
issuesreadonly Issue[]undefined
limit?number3

Returns ​

string

Released under the MIT License.