{"version":3,"file":"index.mjs","names":[],"sources":["../src/builder/validate.ts","../src/builder/exchange.ts","../src/builder/message.ts","../src/builder/queue-utils.ts","../src/builder/binding.ts","../src/builder/ttl-backoff.ts","../src/builder/queue.ts","../src/builder/publisher.ts","../src/builder/consumer.ts","../src/builder/command.ts","../src/builder/event.ts","../src/builder/contract.ts","../src/builder/rpc.ts","../src/issues.ts"],"sourcesContent":["/**\n * Define-time structural validation shared by the builders.\n *\n * The type system already rejects wrong shapes for TypeScript callers, but a\n * JavaScript caller (or a cast) can pass misspelled option keys that were\n * previously ignored silently — a typo like `durabel: false` produced a\n * durable queue with no warning. Per the org DNA (\"typo = define-time\n * failure\", mirroring temporal-contract's contract-shape validation), the\n * builders now throw at definition time with an actionable message.\n *\n * All helpers use the `_internal_` prefix: exported for use across the\n * builder modules, no semver guarantee.\n */\n\n/** Throw unless `name` is a non-empty string (AMQP names must not be blank). */\nexport function _internal_assertNonEmptyName(kind: string, name: unknown): void {\n  if (typeof name !== \"string\" || name.length === 0) {\n    throw new Error(`${kind} name must be a non-empty string, got ${JSON.stringify(name)}`);\n  }\n}\n\n/**\n * Throw when an options bag carries keys outside the allowed set. Lists both\n * the offending keys and the allowed ones so a typo is a one-glance fix.\n */\nexport function _internal_assertKnownKeys(\n  kind: string,\n  name: string,\n  bag: object | undefined,\n  allowed: readonly string[],\n): void {\n  if (bag === undefined) return;\n  const unknown = Object.keys(bag).filter((key) => !allowed.includes(key));\n  if (unknown.length > 0) {\n    throw new Error(\n      `Unknown option${unknown.length > 1 ? \"s\" : \"\"} ${unknown.map((k) => `\"${k}\"`).join(\", \")} ` +\n        `on ${kind} \"${name}\". Allowed options: ${allowed.join(\", \")}.`,\n    );\n  }\n}\n\n/**\n * Duck-check that a value implements Standard Schema v1 (has a `~standard`\n * object with a `validate` function) — catches passing a plain object or a\n * schema from an incompatible library where a payload schema is expected.\n */\nexport function _internal_assertStandardSchema(kind: string, schema: unknown): void {\n  // ArkType schemas are callable, so accept functions as well as objects.\n  const standard =\n    (typeof schema === \"object\" || typeof schema === \"function\") && schema !== null\n      ? (schema as Record<string, unknown>)[\"~standard\"]\n      : undefined;\n  const validate =\n    typeof standard === \"object\" && standard !== null\n      ? (standard as Record<string, unknown>)[\"validate\"]\n      : undefined;\n  if (typeof validate !== \"function\") {\n    throw new Error(\n      `${kind} must be a Standard Schema v1 (an object exposing \"~standard\".validate) — ` +\n        \"got a value without one. Zod, Valibot, and ArkType schemas all qualify.\",\n    );\n  }\n}\n","import type {\n  BaseExchangeDefinition,\n  DirectExchangeDefinition,\n  ExchangeDefinition,\n  FanoutExchangeDefinition,\n  HeadersExchangeDefinition,\n  TopicExchangeDefinition,\n} from \"../types.js\";\nimport { _internal_assertKnownKeys, _internal_assertNonEmptyName } from \"./validate.js\";\n\n/**\n * Define a topic exchange.\n *\n * A topic exchange routes messages to queues based on routing key patterns.\n * Routing keys can use wildcards: `*` matches one word, `#` matches zero or more words.\n * This exchange type is ideal for flexible message routing based on hierarchical topics.\n *\n * @param name - The name of the exchange\n * @param options - Optional exchange configuration\n * @param options.type - Exchange type (must be \"topic\", or omitted for default topic exchange)\n * @param options.durable - If true, the exchange survives broker restarts (default: true)\n * @param options.autoDelete - If true, the exchange is deleted when no queues are bound\n * @param options.internal - If true, the exchange cannot be directly published to\n * @param options.arguments - Additional AMQP arguments for the exchange\n * @returns A topic exchange definition\n *\n * @example\n * ```typescript\n * const ordersExchange = defineExchange('orders', { type: 'topic' });\n *\n * // Or omit type for default topic exchange\n * const ordersExchange = defineExchange('orders');\n * ```\n */\nexport function defineExchange<TName extends string>(\n  name: TName,\n  options?: { type?: \"topic\" } & Omit<BaseExchangeDefinition, \"name\" | \"type\">,\n): TopicExchangeDefinition<TName>;\n\n/**\n * Define a direct exchange.\n *\n * A direct exchange routes messages to queues based on exact routing key matches.\n * This exchange type is ideal for point-to-point messaging.\n *\n * @param name - The name of the exchange\n * @param options - Exchange configuration\n * @param options.type - Exchange type (must be \"direct\")\n * @param options.durable - If true, the exchange survives broker restarts (default: true)\n * @param options.autoDelete - If true, the exchange is deleted when no queues are bound\n * @param options.internal - If true, the exchange cannot be directly published to\n * @param options.arguments - Additional AMQP arguments for the exchange\n * @returns A direct exchange definition\n *\n * @example\n * ```typescript\n * const tasksExchange = defineExchange('tasks', { type: 'direct' });\n * ```\n */\nexport function defineExchange<TName extends string>(\n  name: TName,\n  options: { type: \"direct\" } & Omit<BaseExchangeDefinition, \"name\" | \"type\">,\n): DirectExchangeDefinition<TName>;\n\n/**\n * Define a fanout exchange.\n *\n * A fanout exchange routes messages to all bound queues without considering routing keys.\n * This exchange type is ideal for broadcasting messages to multiple consumers.\n *\n * @param name - The name of the exchange\n * @param options - Exchange configuration\n * @param options.type - Exchange type (must be \"fanout\")\n * @param options.durable - If true, the exchange survives broker restarts (default: true)\n * @param options.autoDelete - If true, the exchange is deleted when no queues are bound\n * @param options.internal - If true, the exchange cannot be directly published to\n * @param options.arguments - Additional AMQP arguments for the exchange\n * @returns A fanout exchange definition\n *\n * @example\n * ```typescript\n * const logsExchange = defineExchange('logs', { type: 'fanout' });\n * ```\n */\nexport function defineExchange<TName extends string>(\n  name: TName,\n  options: { type: \"fanout\" } & Omit<BaseExchangeDefinition, \"name\" | \"type\">,\n): FanoutExchangeDefinition<TName>;\n\n/**\n * Define a headers exchange.\n *\n * A headers exchange routes messages to all bound queues based on header matching.\n * This exchange type is ideal for complex routing scenarios.\n *\n * @param name - The name of the exchange\n * @param options - Exchange configuration\n * @param options.type - Exchange type (must be \"headers\")\n * @param options.durable - If true, the exchange survives broker restarts (default: true)\n * @param options.autoDelete - If true, the exchange is deleted when no queues are bound\n * @param options.internal - If true, the exchange cannot be directly published to\n * @param options.arguments - Additional AMQP arguments for the exchange\n * @returns A headers exchange definition\n *\n * @example\n * ```typescript\n * const routesExchange = defineExchange('routes', { type: 'headers' });\n * ```\n */\nexport function defineExchange<TName extends string>(\n  name: TName,\n  options: { type: \"headers\" } & Omit<BaseExchangeDefinition, \"name\" | \"type\">,\n): HeadersExchangeDefinition<TName>;\n\n/**\n * Define an AMQP exchange.\n *\n * An exchange receives messages from publishers and routes them to queues based on the exchange type\n * and routing rules. This is the implementation function - use the type-specific overloads for better\n * type safety.\n *\n * @param name - The name of the exchange\n * @param options - Optional exchange configuration\n * @param options.type - Exchange type (one of \"topic\", \"direct\", \"fanout\", \"headers\") (default: \"topic\")\n * @param options.durable - If true, the exchange survives broker restarts (default: true)\n * @param options.autoDelete - If true, the exchange is deleted when no queues are bound\n * @param options.internal - If true, the exchange cannot be directly published to\n * @param options.arguments - Additional AMQP arguments for the exchange\n * @returns An exchange definition\n * @internal\n */\nexport function defineExchange(\n  name: string,\n  options?: { type?: \"topic\" | \"direct\" | \"fanout\" | \"headers\" } & Omit<\n    BaseExchangeDefinition,\n    \"name\" | \"type\"\n  >,\n): ExchangeDefinition {\n  _internal_assertNonEmptyName(\"Exchange\", name);\n  _internal_assertKnownKeys(\"exchange\", name, options, [\n    \"type\",\n    \"durable\",\n    \"autoDelete\",\n    \"internal\",\n    \"arguments\",\n  ]);\n  const type = options?.type ?? \"topic\";\n  if (![\"topic\", \"direct\", \"fanout\", \"headers\"].includes(type)) {\n    throw new Error(\n      `Unknown exchange type \"${String(type)}\" for exchange \"${name}\". ` +\n        \"Allowed types: topic, direct, fanout, headers.\",\n    );\n  }\n  return {\n    name,\n    type,\n    durable: true,\n    ...options,\n  };\n}\n","import type { MessageDefinition } from \"../types.js\";\nimport { _internal_assertKnownKeys, _internal_assertStandardSchema } from \"./validate.js\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\n/**\n * Define a message definition with payload and optional headers/metadata.\n *\n * A message definition specifies the schema for message payloads and headers using\n * Standard Schema v1 compatible libraries (Zod, Valibot, ArkType, etc.).\n * The schemas are used for automatic validation when publishing or consuming messages.\n *\n * @param payload - The payload schema (must be Standard Schema v1 compatible)\n * @param options - Optional message metadata\n * @param options.headers - Optional header schema for message headers\n * @param options.summary - Brief description for documentation (used in AsyncAPI generation)\n * @param options.description - Detailed description for documentation (used in AsyncAPI generation)\n * @returns A message definition with inferred types\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const orderMessage = defineMessage(\n *   z.object({\n *     orderId: z.string().uuid(),\n *     customerId: z.string().uuid(),\n *     amount: z.number().positive(),\n *     items: z.array(z.object({\n *       productId: z.string(),\n *       quantity: z.number().int().positive(),\n *     })),\n *   }),\n *   {\n *     summary: 'Order created event',\n *     description: 'Emitted when a new order is created in the system'\n *   }\n * );\n * ```\n */\nexport function defineMessage<\n  TPayload extends MessageDefinition[\"payload\"],\n  THeaders extends StandardSchemaV1<Record<string, unknown>> | undefined = undefined,\n>(\n  payload: TPayload,\n  options?: {\n    headers?: THeaders;\n    summary?: string;\n    description?: string;\n  },\n): MessageDefinition<TPayload, THeaders> {\n  _internal_assertStandardSchema(\"Message payload schema\", payload);\n  _internal_assertKnownKeys(\"message\", \"(anonymous)\", options, [\n    \"headers\",\n    \"summary\",\n    \"description\",\n  ]);\n  if (options?.headers !== undefined) {\n    _internal_assertStandardSchema(\"Message headers schema\", options.headers);\n  }\n  return {\n    payload,\n    ...options,\n  };\n}\n","import type { ExtractQueueFromEntry, QueueDefinition, QueueEntry } from \"../types.js\";\nimport { isQueueWithTtlBackoffInfrastructure } from \"./ttl-backoff.js\";\n\n/**\n * Extract the plain QueueDefinition from a QueueEntry.\n * @internal\n */\nfunction extractQueueFromEntry(entry: QueueEntry): QueueDefinition {\n  if (isQueueWithTtlBackoffInfrastructure(entry)) {\n    return entry.queue;\n  }\n  return entry;\n}\n\n/**\n * Extract the plain QueueDefinition from a QueueEntry.\n *\n * **Why this function exists:**\n * When you configure a queue with TTL-backoff retry,\n * `defineQueue` returns a wrapper object that includes\n * the main queue, wait queue, headers exchanges, and bindings. This function extracts the underlying\n * queue definition so you can access properties like `name`, `type`, etc.\n *\n * **When to use:**\n * - When you need to access queue properties (name, type, etc.)\n * - When passing a queue to functions that expect a plain QueueDefinition\n * - Works safely on both plain queues and infrastructure wrappers\n *\n * **How it works:**\n * - If the entry is a `QueueWithTtlBackoffInfrastructure`, returns `entry.queue`\n * - Otherwise, returns the entry as-is (it's already a plain QueueDefinition)\n *\n * @param entry - The queue entry (either plain QueueDefinition or QueueWithTtlBackoffInfrastructure)\n * @returns The plain QueueDefinition\n *\n * @example\n * ```typescript\n * import { defineQueue, extractQueue } from '@amqp-contract/contract';\n *\n * // TTL-backoff queue returns a wrapper\n * const orderQueue = defineQueue('orders', {\n *   retry: { mode: 'ttl-backoff', maxRetries: 3 },\n * });\n *\n * // Use extractQueue to access the queue name\n * const queueName = extractQueue(orderQueue).name; // 'orders'\n *\n * // Also works safely on plain queues\n * const plainQueue = defineQueue('simple', { type: 'quorum', retry: { mode: 'immediate-requeue' } });\n * const plainName = extractQueue(plainQueue).name; // 'simple'\n *\n * // Access other properties\n * const queueDef = extractQueue(orderQueue);\n * console.log(queueDef.name);       // 'orders'\n * console.log(queueDef.type);       // 'quorum'\n * ```\n *\n * @see isQueueWithTtlBackoffInfrastructure - Type guard to check if extraction is needed\n */\nexport function extractQueue<T extends QueueEntry>(entry: T): ExtractQueueFromEntry<T> {\n  return extractQueueFromEntry(entry) as ExtractQueueFromEntry<T>;\n}\n","import type {\n  DirectExchangeDefinition,\n  ExchangeBindingDefinition,\n  ExchangeDefinition,\n  FanoutExchangeDefinition,\n  HeadersExchangeDefinition,\n  QueueBindingDefinition,\n  QueueEntry,\n  TopicExchangeDefinition,\n} from \"../types.js\";\nimport { extractQueue } from \"./queue-utils.js\";\n\n/**\n * Define a binding between a queue and a fanout or headers exchange.\n *\n * Binds a queue to a fanout or headers exchange (no routing key needed).\n * Fanout and headers exchanges ignore routing keys, so this overload doesn't require one.\n *\n * @param queue - The queue definition or queue with infrastructure to bind\n * @param exchange - The fanout or headers exchange definition\n * @param options - Optional binding configuration\n * @param options.arguments - Additional AMQP arguments for the binding\n * @returns A queue binding definition\n *\n * @example\n * ```typescript\n * const logsQueue = defineQueue('logs-queue');\n * const logsExchange = defineExchange('logs', { type: 'fanout' });\n *\n * const binding = defineQueueBinding(logsQueue, logsExchange);\n * ```\n */\nexport function defineQueueBinding(\n  queue: QueueEntry,\n  exchange: FanoutExchangeDefinition | HeadersExchangeDefinition,\n  options?: Omit<\n    Extract<\n      QueueBindingDefinition,\n      { exchange: FanoutExchangeDefinition | HeadersExchangeDefinition }\n    >,\n    \"type\" | \"queue\" | \"exchange\" | \"routingKey\"\n  >,\n): Extract<\n  QueueBindingDefinition,\n  { exchange: FanoutExchangeDefinition | HeadersExchangeDefinition }\n>;\n\n/**\n * Define a binding between a queue and a direct or topic exchange.\n *\n * Binds a queue to an exchange with a specific routing key pattern.\n * Messages are only routed to the queue if the routing key matches the pattern.\n *\n * For direct exchanges: The routing key must match exactly.\n * For topic exchanges: The routing key can include wildcards:\n * - `*` matches exactly one word\n * - `#` matches zero or more words\n *\n * @param queue - The queue definition or queue with infrastructure to bind\n * @param exchange - The direct or topic exchange definition\n * @param options - Binding configuration (routingKey is required)\n * @param options.routingKey - The routing key pattern for message routing\n * @param options.arguments - Additional AMQP arguments for the binding\n * @returns A queue binding definition\n *\n * @example\n * ```typescript\n * const orderQueue = defineQueue('order-processing');\n * const ordersExchange = defineExchange('orders');\n *\n * // Bind with exact routing key\n * const binding = defineQueueBinding(orderQueue, ordersExchange, {\n *   routingKey: 'order.created'\n * });\n *\n * // Bind with wildcard pattern\n * const allOrdersBinding = defineQueueBinding(orderQueue, ordersExchange, {\n *   routingKey: 'order.*'  // Matches order.created, order.updated, etc.\n * });\n * ```\n */\nexport function defineQueueBinding(\n  queue: QueueEntry,\n  exchange: DirectExchangeDefinition | TopicExchangeDefinition,\n  options: Omit<\n    Extract<\n      QueueBindingDefinition,\n      { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n    >,\n    \"type\" | \"queue\" | \"exchange\"\n  >,\n): Extract<\n  QueueBindingDefinition,\n  { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n>;\n\n/**\n * Define a binding between a queue and an exchange.\n *\n * This is the implementation function - use the type-specific overloads for better type safety.\n *\n * @param queue - The queue definition or queue with infrastructure to bind\n * @param exchange - The exchange definition\n * @param options - Optional binding configuration\n * @returns A queue binding definition\n * @internal\n */\nexport function defineQueueBinding(\n  queue: QueueEntry,\n  exchange: ExchangeDefinition,\n  options?: {\n    routingKey?: string;\n    arguments?: Record<string, unknown>;\n  },\n): QueueBindingDefinition {\n  // Extract the plain queue definition from QueueEntry\n  const queueDef = extractQueue(queue);\n\n  if (exchange.type === \"fanout\" || exchange.type === \"headers\") {\n    return {\n      type: \"queue\",\n      queue: queueDef,\n      exchange,\n      ...(options?.arguments && { arguments: options.arguments }),\n    } as QueueBindingDefinition;\n  }\n\n  return {\n    type: \"queue\",\n    queue: queueDef,\n    exchange,\n    routingKey: options?.routingKey,\n    ...(options?.arguments && { arguments: options.arguments }),\n  } as QueueBindingDefinition;\n}\n\n/**\n * Internal helper to call defineQueueBinding with proper type handling.\n * Used by queue.ts to avoid circular dependency.\n * @internal\n */\nexport function defineQueueBindingInternal(\n  queue: QueueEntry,\n  exchange: ExchangeDefinition,\n  options?: {\n    routingKey?: string;\n    arguments?: Record<string, unknown>;\n  },\n): QueueBindingDefinition {\n  if (exchange.type === \"fanout\" || exchange.type === \"headers\") {\n    return defineQueueBinding(queue, exchange, options);\n  }\n  return defineQueueBinding(queue, exchange, options as { routingKey: string });\n}\n\n/**\n * Define a binding between two exchanges (exchange-to-exchange routing).\n *\n * Binds a destination exchange to a fanout or headers source exchange.\n * Messages published to the source exchange will be forwarded to the destination exchange.\n * Fanout and headers exchanges ignore routing keys, so this overload doesn't require one.\n *\n * @param destination - The destination exchange definition\n * @param source - The fanout or headers source exchange definition\n * @param options - Optional binding configuration\n * @param options.arguments - Additional AMQP arguments for the binding\n * @returns An exchange binding definition\n *\n * @example\n * ```typescript\n * const sourceExchange = defineExchange('logs', { type: 'fanout' });\n * const destExchange = defineExchange('all-logs', { type: 'fanout' });\n *\n * const binding = defineExchangeBinding(destExchange, sourceExchange);\n * ```\n */\nexport function defineExchangeBinding(\n  destination: ExchangeDefinition,\n  source: FanoutExchangeDefinition | HeadersExchangeDefinition,\n  options?: Omit<\n    Extract<\n      ExchangeBindingDefinition,\n      { source: FanoutExchangeDefinition | HeadersExchangeDefinition }\n    >,\n    \"type\" | \"source\" | \"destination\" | \"routingKey\"\n  >,\n): Extract<\n  ExchangeBindingDefinition,\n  { source: FanoutExchangeDefinition | HeadersExchangeDefinition }\n>;\n\n/**\n * Define a binding between two exchanges (exchange-to-exchange routing).\n *\n * Binds a destination exchange to a direct or topic source exchange with a routing key pattern.\n * Messages are forwarded from source to destination only if the routing key matches the pattern.\n *\n * @param destination - The destination exchange definition\n * @param source - The direct or topic source exchange definition\n * @param options - Binding configuration (routingKey is required)\n * @param options.routingKey - The routing key pattern for message routing\n * @param options.arguments - Additional AMQP arguments for the binding\n * @returns An exchange binding definition\n *\n * @example\n * ```typescript\n * const ordersExchange = defineExchange('orders');\n * const importantExchange = defineExchange('important-orders');\n *\n * // Forward only high-value orders\n * const binding = defineExchangeBinding(importantExchange, ordersExchange, {\n *   routingKey: 'order.high-value.*'\n * });\n * ```\n */\nexport function defineExchangeBinding(\n  destination: ExchangeDefinition,\n  source: DirectExchangeDefinition | TopicExchangeDefinition,\n  options: Omit<\n    Extract<\n      ExchangeBindingDefinition,\n      { source: DirectExchangeDefinition | TopicExchangeDefinition }\n    >,\n    \"type\" | \"source\" | \"destination\"\n  >,\n): Extract<\n  ExchangeBindingDefinition,\n  { source: DirectExchangeDefinition | TopicExchangeDefinition }\n>;\n\n/**\n * Define a binding between two exchanges (exchange-to-exchange routing).\n *\n * This is the implementation function - use the type-specific overloads for better type safety.\n *\n * @param destination - The destination exchange definition\n * @param source - The source exchange definition\n * @param options - Optional binding configuration\n * @returns An exchange binding definition\n * @internal\n */\nexport function defineExchangeBinding(\n  destination: ExchangeDefinition,\n  source: ExchangeDefinition,\n  options?: {\n    routingKey?: string;\n    arguments?: Record<string, unknown>;\n  },\n): ExchangeBindingDefinition {\n  if (source.type === \"fanout\" || source.type === \"headers\") {\n    return {\n      type: \"exchange\",\n      source,\n      destination,\n      ...(options?.arguments && { arguments: options.arguments }),\n    } as ExchangeBindingDefinition;\n  }\n\n  return {\n    type: \"exchange\",\n    source,\n    destination,\n    routingKey: options?.routingKey ?? \"\",\n    ...(options?.arguments && { arguments: options.arguments }),\n  } as ExchangeBindingDefinition;\n}\n","import type {\n  BaseQueueDefinition,\n  QueueDefinition,\n  QueueEntry,\n  QueueWithTtlBackoffInfrastructure,\n  TtlBackoffRetryInfrastructure,\n} from \"../types.js\";\nimport { defineQueueBindingInternal } from \"./binding.js\";\nimport { defineExchange } from \"./exchange.js\";\n\n/**\n * Type guard to check if a queue entry is a QueueWithTtlBackoffInfrastructure.\n *\n * When you configure a queue with TTL-backoff retry,\n * `defineQueue` returns a `QueueWithTtlBackoffInfrastructure` instead of a plain\n * `QueueDefinition`. This type guard helps you distinguish between the two.\n *\n * **When to use:**\n * - When you need to check the type of a queue entry at runtime\n * - When writing generic code that handles both plain queues and infrastructure wrappers\n *\n * **Related functions:**\n * - `extractQueue()` - Use this to get the underlying queue definition from either type\n *\n * @param entry - The queue entry to check\n * @returns True if the entry is a QueueWithTtlBackoffInfrastructure, false otherwise\n *\n * @example\n * ```typescript\n * const queue = defineQueue('orders', {\n *   retry: { mode: 'ttl-backoff' },\n * });\n *\n * if (isQueueWithTtlBackoffInfrastructure(queue)) {\n *   // queue has .queue, .waitQueue, .waitQueueBinding, .retryQueueBinding, .waitExchange, .retryExchange\n *   console.log('Wait queue:', queue.waitQueue.name);\n * } else {\n *   // queue is a plain QueueDefinition\n *   console.log('Queue:', queue.name);\n * }\n * ```\n */\nexport function isQueueWithTtlBackoffInfrastructure(\n  entry: QueueEntry,\n): entry is QueueWithTtlBackoffInfrastructure {\n  return (\n    typeof entry === \"object\" &&\n    entry !== null &&\n    \"__brand\" in entry &&\n    entry.__brand === \"QueueWithTtlBackoffInfrastructure\"\n  );\n}\n\n/**\n * Wrap a queue definition with TTL-backoff retry infrastructure.\n */\nexport function wrapWithTtlBackoffInfrastructure(\n  queue: QueueDefinition,\n): QueueWithTtlBackoffInfrastructure {\n  const infra = createTtlBackoffInfrastructure(queue);\n\n  return {\n    __brand: \"QueueWithTtlBackoffInfrastructure\",\n    queue,\n    ...infra,\n  };\n}\n\n/**\n * Create TTL-backoff retry infrastructure for a queue.\n *\n * This builder helper generates the wait queue, exchanges, and bindings needed for TTL-backoff retry.\n * The generated infrastructure can be spread into a contract definition.\n *\n * TTL-backoff retry works by:\n * 1. Failed messages are sent to the wait exchange with header `x-wait-queue` set to the wait queue name\n * 2. The wait queue receives these messages and holds them for a TTL period\n * 3. After TTL expires, messages are dead-lettered back to the retry exchange with header `x-retry-queue` set to the main queue name\n * 4. The main queue receives the retried message via its binding to the retry exchange\n *\n * @param queue - The main queue definition\n * @param options - Optional configuration for the wait queue\n * @returns TTL-backoff retry infrastructure containing wait queue and bindings\n * @throws {Error} If the queue does not have retry mode set to `ttl-backoff`\n *\n * @example\n * ```typescript\n * const orderQueue = defineQueue('order-processing', {\n *   type: 'quorum',\n *   retry: {\n *     mode: 'ttl-backoff',\n *     maxRetries: 5,\n *     initialDelayMs: 1000,\n *   },\n * });\n *\n * // Infrastructure is auto-extracted when using defineContract:\n * const contract = defineContract({\n *   publishers: { ... },\n *   consumers: { processOrder: defineEventConsumer(event, orderQueue) },\n * });\n * // contract.queues includes the wait queue, contract.exchanges includes retry exchanges, contract.bindings includes retry bindings\n * ```\n */\nexport function createTtlBackoffInfrastructure(\n  queue: QueueDefinition,\n): TtlBackoffRetryInfrastructure {\n  // Ensure queue retry mode is ttl-backoff\n  if (queue.retry.mode !== \"ttl-backoff\") {\n    throw new Error(\n      `Queue ${queue.name} does not have ttl-backoff retry mode. Infrastructure can only be created for queues with ttl-backoff retry.`,\n    );\n  }\n\n  // Create wait exchange (headers exchange) for routing failed messages to the wait queue\n  const waitExchange = defineExchange(queue.retry.waitExchangeName, {\n    type: \"headers\",\n  });\n\n  // Create retry exchange (headers exchange) for routing messages to retry back to main queue\n  const retryExchange = defineExchange(queue.retry.retryExchangeName, {\n    type: \"headers\",\n  });\n\n  // Create the wait queue (of same type as main queue)\n  const baseWaitQueue: BaseQueueDefinition = {\n    name: queue.retry.waitQueueName,\n    deadLetter: {\n      exchange: retryExchange, // Routes back to retry exchange after TTL (will preserve original message routing key)\n    },\n    retry: { mode: \"none\" }, // No retry for wait queue itself\n  };\n\n  const waitQueue: QueueDefinition =\n    queue.type === \"quorum\"\n      ? {\n          ...baseWaitQueue,\n          type: queue.type,\n          durable: true, // Quorum queues are always durable\n        }\n      : {\n          ...baseWaitQueue,\n          type: queue.type,\n          durable: queue.durable,\n        };\n\n  // Create binding for wait queue to receive failed messages\n  const waitQueueBinding = defineQueueBindingInternal(waitQueue, waitExchange, {\n    arguments: {\n      \"x-match\": \"all\",\n      \"x-wait-queue\": waitQueue.name, // Custom header to specify the wait queue to which messages should be routed\n    },\n  });\n\n  // Create binding for main queue to receive messages to retry\n  const retryQueueBinding = defineQueueBindingInternal(queue, retryExchange, {\n    arguments: {\n      \"x-match\": \"all\",\n      \"x-retry-queue\": queue.name, // Custom header to specify the retry queue to which messages should be routed\n    },\n  });\n\n  return {\n    waitQueue,\n    waitExchange,\n    retryExchange,\n    waitQueueBinding,\n    retryQueueBinding,\n  };\n}\n","import type {\n  BaseQueueDefinition,\n  DeadLetterConfig,\n  DefineQueueOptions,\n  DefineQueueOptionsWithDeadLetterExchange,\n  ExchangeDefinition,\n  ImmediateRequeueRetryOptions,\n  QueueDefinition,\n  QueueEntry,\n  QueueEntryWithDeadLetterExchange,\n  ResolvedImmediateRequeueRetryOptions,\n  ResolvedTtlBackoffRetryOptions,\n  TtlBackoffRetryOptions,\n} from \"../types.js\";\nimport { _internal_assertKnownKeys, _internal_assertNonEmptyName } from \"./validate.js\";\nimport { wrapWithTtlBackoffInfrastructure } from \"./ttl-backoff.js\";\n\n/**\n * Resolve immediate-requeue retry options with defaults.\n * @internal\n */\nfunction resolveImmediateRequeueOptions(\n  options: ImmediateRequeueRetryOptions | undefined,\n): ResolvedImmediateRequeueRetryOptions {\n  return {\n    mode: \"immediate-requeue\",\n    maxRetries: options?.maxRetries ?? 3,\n  };\n}\n\n/**\n * Resolve TTL-backoff retry options with defaults.\n * @internal\n */\nfunction resolveTtlBackoffOptions(\n  queueName: string,\n  options: TtlBackoffRetryOptions | undefined,\n): ResolvedTtlBackoffRetryOptions {\n  return {\n    mode: \"ttl-backoff\",\n    maxRetries: options?.maxRetries ?? 3,\n    initialDelayMs: options?.initialDelayMs ?? 1000,\n    maxDelayMs: options?.maxDelayMs ?? 30000,\n    backoffMultiplier: options?.backoffMultiplier ?? 2,\n    jitter: options?.jitter ?? true,\n    waitQueueName: options?.waitQueueName ?? `${queueName}-wait`,\n    waitExchangeName: options?.waitExchangeName ?? \"wait-exchange\",\n    retryExchangeName: options?.retryExchangeName ?? \"retry-exchange\",\n  };\n}\n\n/**\n * Define an AMQP queue.\n *\n * A queue stores messages until they are consumed by workers. Queues can be bound to exchanges\n * to receive messages based on routing rules.\n *\n * By default, queues are created as quorum queues which provide better durability and\n * high-availability. Use `type: 'classic'` for special cases like non-durable queues\n * or priority queues.\n *\n * @param name - The name of the queue\n * @param options - Optional queue configuration\n * @param options.type - Queue type: 'quorum' (default, recommended) or 'classic'\n * @param options.durable - If true, the queue survives broker restarts. Quorum queues only support durable queues (default: true)\n * @param options.exclusive - If true, the queue can only be used by the declaring connection and is deleted when that connection closes. Only supported with classic queues.\n * @param options.autoDelete - If true, the queue is deleted when the last consumer unsubscribes. Only supported with classic queues.\n * @param options.maxPriority - Maximum priority level for priority queue (1-255, recommended: 1-10). Only supported with classic queues.\n * @param options.deadLetter - Dead letter configuration for handling failed messages\n * @param options.retry - Retry configuration for handling failed message processing\n * @param options.arguments - Additional AMQP arguments (e.g., x-message-ttl)\n * @returns A queue definition\n *\n * @example\n * ```typescript\n * // Quorum queue (default, recommended for production)\n * const orderQueue = defineQueue('order-processing');\n *\n * // Explicit quorum queue with dead letter exchange\n * const dlx = defineExchange('orders-dlx');\n * const orderQueueWithDLX = defineQueue('order-processing', {\n *   type: 'quorum',\n *   deadLetter: {\n *     exchange: dlx,\n *     routingKey: 'order.failed'\n *   },\n *   arguments: {\n *     'x-message-ttl': 86400000, // 24 hours\n *   }\n * });\n *\n * // Classic queue (for special cases)\n * const tempQueue = defineQueue('temp-queue', {\n *   type: 'classic',\n *   durable: false,\n *   autoDelete: true,\n * });\n *\n * // Priority queue (requires classic type)\n * const taskQueue = defineQueue('urgent-tasks', {\n *   type: 'classic',\n *   maxPriority: 10,\n * });\n *\n * // Queue with TTL-backoff retry (returns infrastructure automatically)\n * const dlx = defineExchange('orders-dlx', { type: 'direct' });\n * const orderQueue = defineQueue('order-processing', {\n *   deadLetter: { exchange: dlx },\n *   retry: { mode: 'ttl-backoff', maxRetries: 5 },\n * });\n * // orderQueue is QueueWithTtlBackoffInfrastructure, pass directly to defineContract\n * ```\n */\nexport function defineQueue<TName extends string, TDlx extends ExchangeDefinition>(\n  name: TName,\n  options: DefineQueueOptionsWithDeadLetterExchange<TDlx>,\n): QueueEntryWithDeadLetterExchange<TName, TDlx>;\n\nexport function defineQueue<TName extends string>(\n  name: TName,\n  options?: DefineQueueOptions,\n): QueueEntry<TName>;\n\nexport function defineQueue(name: string, options?: DefineQueueOptions): QueueEntry {\n  _internal_assertNonEmptyName(\"Queue\", name);\n  _internal_assertKnownKeys(\"queue\", name, options, [\n    \"type\",\n    \"durable\",\n    \"exclusive\",\n    \"autoDelete\",\n    \"maxPriority\",\n    \"deadLetter\",\n    \"retry\",\n    \"arguments\",\n  ]);\n  if (options?.deadLetter !== undefined) {\n    _internal_assertKnownKeys(\"queue deadLetter config of\", name, options.deadLetter, [\n      \"exchange\",\n      \"routingKey\",\n    ]);\n  }\n  if (options?.retry !== undefined) {\n    _internal_assertKnownKeys(\"queue retry config of\", name, options.retry, [\n      \"mode\",\n      \"maxRetries\",\n      \"initialDelayMs\",\n      \"maxDelayMs\",\n      \"backoffMultiplier\",\n      \"jitter\",\n      \"waitQueueName\",\n      \"waitExchangeName\",\n      \"retryExchangeName\",\n    ]);\n  }\n  const opts = options ?? {};\n  const type = opts.type ?? \"quorum\";\n  const durable = opts.durable ?? true;\n\n  // Build base properties shared by both queue types\n  const baseProps: {\n    name: string;\n    deadLetter?: DeadLetterConfig;\n    arguments?: Record<string, unknown>;\n  } = {\n    name,\n    ...(opts.deadLetter !== undefined && { deadLetter: opts.deadLetter }),\n    ...(opts.arguments !== undefined && { arguments: opts.arguments }),\n  };\n\n  // Build specific properties for classic queues\n  const classicProps: {\n    exclusive?: boolean;\n    autoDelete?: boolean;\n    maxPriority?: number;\n  } = {\n    ...(opts.exclusive !== undefined && { exclusive: opts.exclusive }),\n    ...(opts.autoDelete !== undefined && { autoDelete: opts.autoDelete }),\n    ...(opts.maxPriority !== undefined && { maxPriority: opts.maxPriority }),\n  };\n\n  if (type === \"quorum\") {\n    // Quorum queues do not support non-durable, exclusive, autoDelete, or maxPriority\n    if (opts.durable === false) {\n      throw new Error(\"Non-durable queues are not supported with quorum type.\");\n    }\n    if (opts.exclusive !== undefined) {\n      throw new Error(\"Exclusive queues are not supported with quorum type.\");\n    }\n    if (opts.autoDelete !== undefined) {\n      throw new Error(\"Auto-deleting queues are not supported with quorum type.\");\n    }\n    if (opts.maxPriority !== undefined) {\n      throw new Error(\"Priority queues are not supported with quorum type.\");\n    }\n  } else {\n    // Validate maxPriority\n    if (opts.maxPriority !== undefined) {\n      if (opts.maxPriority < 1 || opts.maxPriority > 255) {\n        throw new Error(\n          `Invalid maxPriority: ${opts.maxPriority}. Must be between 1 and 255. Recommended range: 1-10.`,\n        );\n      }\n    }\n  }\n\n  const inputRetry = opts.retry ?? { mode: \"none\" as const };\n\n  // Validate retry requirements\n  if (inputRetry.mode === \"immediate-requeue\" || inputRetry.mode === \"ttl-backoff\") {\n    if (inputRetry.maxRetries !== undefined) {\n      if (inputRetry.maxRetries < 1 || !Number.isInteger(inputRetry.maxRetries)) {\n        throw new Error(\n          `Queue \"${name}\" uses ${inputRetry.mode} retry mode with invalid maxRetries: ${inputRetry.maxRetries}. Must be a positive integer.`,\n        );\n      }\n    }\n  }\n\n  // Resolve retry options with defaults\n  const retry =\n    inputRetry.mode === \"immediate-requeue\"\n      ? resolveImmediateRequeueOptions(inputRetry)\n      : inputRetry.mode === \"ttl-backoff\"\n        ? resolveTtlBackoffOptions(name, inputRetry)\n        : inputRetry;\n\n  const baseQueueDefinition: BaseQueueDefinition = {\n    ...baseProps,\n    retry,\n  };\n\n  const queueDefinition: QueueDefinition =\n    type === \"quorum\"\n      ? {\n          ...baseQueueDefinition,\n          type,\n          durable: true, // Quorum queues are always durable\n        }\n      : {\n          ...baseQueueDefinition,\n          ...classicProps,\n          type,\n          durable,\n        };\n\n  // If TTL-backoff retry, wrap with infrastructure\n  if (retry.mode === \"ttl-backoff\") {\n    return wrapWithTtlBackoffInfrastructure(queueDefinition);\n  }\n\n  return queueDefinition;\n}\n","import type {\n  DirectExchangeDefinition,\n  ExchangeDefinition,\n  FanoutExchangeDefinition,\n  HeadersExchangeDefinition,\n  MessageDefinition,\n  PublisherDefinition,\n  TopicExchangeDefinition,\n} from \"../types.js\";\n\n/**\n * Define a message publisher for a fanout or headers exchange.\n *\n * A publisher sends messages to an exchange. For fanout exchanges, messages are broadcast\n * to all bound queues regardless of routing key, so no routing key is required. For headers exchanges,\n * routing is based on message headers rather than routing keys, so no routing key is required either.\n *\n * The message schema is validated when publishing to ensure type safety.\n *\n * **Which pattern to use:**\n *\n * | Pattern | Best for | Description |\n * |---------|----------|-------------|\n * | `definePublisher` + `defineConsumer` | Independent definition | Define publishers and consumers separately with manual schema consistency |\n * | `defineEventPublisher` + `defineEventConsumer` | Event broadcasting | Define event publisher first, create consumers that subscribe to it |\n * | `defineCommandConsumer` + `defineCommandPublisher` | Task queues | Define command consumer first, create publishers that send commands to it |\n *\n * Use `defineEventPublisher` when:\n * - One publisher feeds multiple consumers\n * - You want automatic schema consistency between publisher and consumers\n * - You're building event-driven architectures\n *\n * @param exchange - The fanout or headers exchange definition to publish to\n * @param message - The message definition with payload schema\n * @param options - Optional publisher configuration\n * @returns A publisher definition with inferred message types\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const logsExchange = defineExchange('logs', { type: 'fanout' });\n * const logMessage = defineMessage(\n *   z.object({\n *     level: z.enum(['info', 'warn', 'error']),\n *     message: z.string(),\n *     timestamp: z.string().datetime(),\n *   })\n * );\n *\n * const logPublisher = definePublisher(logsExchange, logMessage);\n * ```\n *\n * @see defineEventPublisher - For event-driven patterns with automatic schema consistency\n * @see defineCommandConsumer - For task queue patterns with automatic schema consistency\n */\nexport function definePublisher<TMessage extends MessageDefinition>(\n  exchange: FanoutExchangeDefinition | HeadersExchangeDefinition,\n  message: TMessage,\n  options?: Omit<\n    Extract<\n      PublisherDefinition<TMessage>,\n      { exchange: FanoutExchangeDefinition | HeadersExchangeDefinition }\n    >,\n    \"exchange\" | \"message\" | \"routingKey\"\n  >,\n): Extract<\n  PublisherDefinition<TMessage>,\n  { exchange: FanoutExchangeDefinition | HeadersExchangeDefinition }\n>;\n\n/**\n * Define a message publisher for a direct or topic exchange.\n *\n * A publisher sends messages to an exchange with a specific routing key.\n * The routing key determines which queues receive the message.\n *\n * The message schema is validated when publishing to ensure type safety.\n *\n * **Which pattern to use:**\n *\n * | Pattern | Best for | Description |\n * |---------|----------|-------------|\n * | `definePublisher` + `defineConsumer` | Independent definition | Define publishers and consumers separately with manual schema consistency |\n * | `defineEventPublisher` + `defineEventConsumer` | Event broadcasting | Define event publisher first, create consumers that subscribe to it |\n * | `defineCommandConsumer` + `defineCommandPublisher` | Task queues | Define command consumer first, create publishers that send commands to it |\n *\n * Use `defineEventPublisher` when:\n * - One publisher feeds multiple consumers\n * - You want automatic schema consistency between publisher and consumers\n * - You're building event-driven architectures\n *\n * @param exchange - The direct or topic exchange definition to publish to\n * @param message - The message definition with payload schema\n * @param options - Publisher configuration (routingKey is required)\n * @param options.routingKey - The routing key for message routing\n * @returns A publisher definition with inferred message types\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const ordersExchange = defineExchange('orders');\n * const orderMessage = defineMessage(\n *   z.object({\n *     orderId: z.string().uuid(),\n *     amount: z.number().positive(),\n *   }),\n *   {\n *     summary: 'Order created event',\n *     description: 'Emitted when a new order is created'\n *   }\n * );\n *\n * const orderCreatedPublisher = definePublisher(ordersExchange, orderMessage, {\n *   routingKey: 'order.created'\n * });\n * ```\n *\n * @see defineEventPublisher - For event-driven patterns with automatic schema consistency\n * @see defineCommandConsumer - For task queue patterns with automatic schema consistency\n */\nexport function definePublisher<TMessage extends MessageDefinition>(\n  exchange: DirectExchangeDefinition | TopicExchangeDefinition,\n  message: TMessage,\n  options: Omit<\n    Extract<\n      PublisherDefinition<TMessage>,\n      { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n    >,\n    \"exchange\" | \"message\"\n  >,\n): Extract<\n  PublisherDefinition<TMessage>,\n  { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n>;\n\n/**\n * Define a message publisher.\n *\n * This is the implementation function - use the type-specific overloads for better type safety.\n *\n * @param exchange - The exchange definition\n * @param message - The message definition\n * @param options - Optional publisher configuration\n * @returns A publisher definition\n * @internal\n */\nexport function definePublisher<TMessage extends MessageDefinition>(\n  exchange: ExchangeDefinition,\n  message: TMessage,\n  options?: { routingKey?: string },\n): PublisherDefinition<TMessage> {\n  if (exchange.type === \"fanout\" || exchange.type === \"headers\") {\n    return {\n      exchange,\n      message,\n    } as PublisherDefinition<TMessage>;\n  }\n\n  return {\n    exchange,\n    message,\n    routingKey: options?.routingKey ?? \"\",\n  } as PublisherDefinition<TMessage>;\n}\n\n/**\n * Helper to call definePublisher with proper type handling.\n * Type safety is enforced by overloaded public function signatures.\n * @internal\n */\nexport function definePublisherInternal<TMessage extends MessageDefinition>(\n  exchange: ExchangeDefinition,\n  message: TMessage,\n  options?: {\n    routingKey?: string;\n    arguments?: Record<string, unknown>;\n  },\n): PublisherDefinition<TMessage> {\n  // Type assertion is safe because overloaded signatures enforce routingKey requirement\n  if (exchange.type === \"fanout\" || exchange.type === \"headers\") {\n    return definePublisher(exchange, message, options);\n  }\n  return definePublisher(exchange, message, options as { routingKey: string });\n}\n","import type {\n  CommandConsumerConfigBase,\n  ConsumerDefinition,\n  ConsumerEntry,\n  EventConsumerResultBase,\n  MessageDefinition,\n  QueueEntry,\n} from \"../types.js\";\n\n/**\n * Type guard to check if an entry is an EventConsumerResult.\n */\nfunction isEventConsumerResultEntry(entry: ConsumerEntry): entry is EventConsumerResultBase {\n  return \"__brand\" in entry && entry.__brand === \"EventConsumerResult\";\n}\n\n/**\n * Type guard to check if an entry is a CommandConsumerConfig.\n */\nfunction isCommandConsumerConfigEntry(entry: ConsumerEntry): entry is CommandConsumerConfigBase {\n  return \"__brand\" in entry && entry.__brand === \"CommandConsumerConfig\";\n}\n\n/**\n * Extract the ConsumerDefinition from any ConsumerEntry type.\n *\n * Handles the following entry types:\n * - ConsumerDefinition: returned as-is\n * - EventConsumerResult: returns the nested `.consumer` property\n * - CommandConsumerConfig: returns the nested `.consumer` property\n *\n * Use this function when you need to access the underlying ConsumerDefinition\n * from a consumer entry that may have been created with defineEventConsumer\n * or defineCommandConsumer.\n *\n * @param entry - The consumer entry to extract from\n * @returns The underlying ConsumerDefinition\n *\n * @example\n * ```typescript\n * // Works with plain ConsumerDefinition\n * const consumer1 = defineConsumer(queue, message);\n * extractConsumer(consumer1).queue.name; // \"my-queue\"\n *\n * // Works with EventConsumerResult\n * const consumer2 = defineEventConsumer(eventPublisher, queue);\n * extractConsumer(consumer2).queue.name; // \"my-queue\"\n *\n * // Works with CommandConsumerConfig\n * const consumer3 = defineCommandConsumer(queue, exchange, message, { routingKey: \"cmd\" });\n * extractConsumer(consumer3).queue.name; // \"my-queue\"\n * ```\n */\nexport function extractConsumer(entry: ConsumerEntry): ConsumerDefinition {\n  if (isEventConsumerResultEntry(entry) || isCommandConsumerConfigEntry(entry)) {\n    return entry.consumer;\n  }\n  // Otherwise it's a plain ConsumerDefinition\n  return entry;\n}\n\n/**\n * Define a message consumer.\n *\n * A consumer receives and processes messages from a queue. The message schema is validated\n * automatically when messages are consumed, ensuring type safety for your handlers.\n *\n * Consumers are associated with a specific queue and message type. When you create a worker\n * with this consumer, it will process messages from the queue according to the schema.\n *\n * **Which pattern to use:**\n *\n * | Pattern | Best for | Description |\n * |---------|----------|-------------|\n * | `definePublisher` + `defineConsumer` | Independent definition | Define publishers and consumers separately with manual schema consistency |\n * | `defineEventPublisher` + `defineEventConsumer` | Event broadcasting | Define event publisher first, create consumers that subscribe to it |\n * | `defineCommandConsumer` + `defineCommandPublisher` | Task queues | Define command consumer first, create publishers that send commands to it |\n *\n * Use `defineCommandConsumer` when:\n * - One consumer receives from multiple publishers\n * - You want automatic schema consistency between consumer and publishers\n * - You're building task queue or command patterns\n *\n * @param queue - The queue definition to consume from\n * @param message - The message definition with payload schema\n * @param options - Optional consumer configuration\n * @returns A consumer definition with inferred message types\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const orderQueue = defineQueue('order-processing');\n * const orderMessage = defineMessage(\n *   z.object({\n *     orderId: z.string().uuid(),\n *     customerId: z.string().uuid(),\n *     amount: z.number().positive(),\n *   })\n * );\n *\n * const processOrderConsumer = defineConsumer(orderQueue, orderMessage);\n *\n * // Later, when creating a worker, you'll provide a handler for this consumer:\n * // const worker = await TypedAmqpWorker.create({\n * //   contract,\n * //   handlers: {\n * //     processOrder: async (message) => {\n * //       // message is automatically typed based on the schema\n * //       console.log(message.orderId); // string\n * //     }\n * //   },\n * //   connection\n * // });\n * ```\n *\n * @see defineCommandConsumer - For task queue patterns with automatic schema consistency\n * @see defineEventPublisher - For event-driven patterns with automatic schema consistency\n */\nexport function defineConsumer<TMessage extends MessageDefinition>(\n  queue: QueueEntry,\n  message: TMessage,\n  options?: Omit<ConsumerDefinition<TMessage>, \"queue\" | \"message\">,\n): ConsumerDefinition<TMessage> {\n  return {\n    queue,\n    message,\n    ...options,\n  };\n}\n","import type {\n  ConsumerDefinition,\n  DirectExchangeDefinition,\n  ExchangeBindingDefinition,\n  ExchangeDefinition,\n  FanoutExchangeDefinition,\n  HeadersExchangeDefinition,\n  MessageDefinition,\n  PublisherDefinition,\n  QueueBindingDefinition,\n  QueueEntry,\n  TopicExchangeDefinition,\n} from \"../types.js\";\nimport { defineExchangeBinding, defineQueueBindingInternal } from \"./binding.js\";\nimport { defineConsumer } from \"./consumer.js\";\nimport { definePublisherInternal } from \"./publisher.js\";\nimport type { BindingPattern, RoutingKey } from \"./routing-types.js\";\n\n/**\n * Configuration for a command consumer.\n *\n * Commands are sent by one or more publishers to a single consumer (task queue pattern).\n * The consumer \"owns\" the queue, and publishers send commands to it.\n *\n * @template TMessage - The message definition\n * @template TExchange - The exchange definition\n * @template TRoutingKey - The routing key type (undefined for fanout and headers exchanges)\n */\nexport type CommandConsumerConfig<\n  TMessage extends MessageDefinition,\n  TExchange extends ExchangeDefinition,\n  TRoutingKey extends string | undefined = undefined,\n  TQueue extends QueueEntry = QueueEntry,\n> = {\n  /** Discriminator to identify this as a command consumer config */\n  __brand: \"CommandConsumerConfig\";\n  /** The consumer definition for processing commands */\n  consumer: ConsumerDefinition<TMessage>;\n  /** The binding connecting the queue to the exchange */\n  binding: QueueBindingDefinition;\n  /** The exchange that receives commands */\n  exchange: TExchange;\n  /** The queue this consumer reads from */\n  queue: TQueue;\n  /** The message definition */\n  message: TMessage;\n  /** The routing key pattern for the binding */\n  routingKey: TRoutingKey;\n};\n\n/**\n * Configuration for a bridged command publisher.\n *\n * A bridged publisher publishes to a bridge exchange (local domain), which forwards\n * messages to the target exchange (remote domain) via an exchange-to-exchange binding.\n *\n * @template TMessage - The message definition\n * @template TBridgeExchange - The bridge (local domain) exchange definition\n * @template TTargetExchange - The target (remote domain) exchange definition\n */\nexport type BridgedPublisherConfig<\n  TMessage extends MessageDefinition,\n  TBridgeExchange extends ExchangeDefinition,\n  TTargetExchange extends ExchangeDefinition,\n> = {\n  /** Discriminator to identify this as a bridged publisher config */\n  __brand: \"BridgedPublisherConfig\";\n  /** The publisher definition (publishes to bridge exchange) */\n  publisher: PublisherDefinition<TMessage>;\n  /** The exchange-to-exchange binding (bridge → target) */\n  exchangeBinding: ExchangeBindingDefinition;\n  /** The bridge (local domain) exchange */\n  bridgeExchange: TBridgeExchange;\n  /** The target (remote domain) exchange */\n  targetExchange: TTargetExchange;\n};\n\n/**\n * Define a command consumer for receiving commands via fanout exchange.\n *\n * Commands are sent by publishers to a specific queue. The consumer \"owns\" the\n * queue and defines what commands it accepts.\n *\n * @param queue - The queue that will receive commands\n * @param exchange - The fanout exchange that routes commands\n * @param message - The message definition (schema and metadata)\n * @param options - Optional binding configuration\n * @param options.arguments - Additional AMQP arguments\n * @returns A command consumer configuration\n *\n * @example\n * ```typescript\n * const tasksExchange = defineExchange('tasks', { type: 'fanout' });\n * const taskMessage = defineMessage(z.object({ taskId: z.string() }));\n *\n * // Consumer owns the queue\n * const executeTask = defineCommandConsumer(taskQueue, tasksExchange, taskMessage);\n *\n * // Publishers send commands to it\n * const sendTask = defineCommandPublisher(executeTask);\n * ```\n */\nexport function defineCommandConsumer<\n  TMessage extends MessageDefinition,\n  TQueueEntry extends QueueEntry,\n  TExchange extends FanoutExchangeDefinition,\n>(\n  queue: TQueueEntry,\n  exchange: TExchange,\n  message: TMessage,\n  options?: {\n    arguments?: Record<string, unknown>;\n  },\n): CommandConsumerConfig<TMessage, TExchange, undefined, TQueueEntry>;\n\n/**\n * Define a command consumer for receiving commands via headers exchange.\n *\n * Commands are sent by publishers to a specific queue. The consumer \"owns\" the\n * queue and defines what commands it accepts.\n *\n * @param queue - The queue that will receive commands\n * @param exchange - The headers exchange that routes commands\n * @param message - The message definition (schema and metadata)\n * @param options - Optional binding configuration\n * @param options.arguments - Additional AMQP arguments\n * @returns A command consumer configuration\n *\n * @example\n * ```typescript\n * const tasksExchange = defineExchange('tasks', { type: 'headers' });\n * const taskMessage = defineMessage(z.object({ taskId: z.string() }));\n *\n * // Consumer owns the queue\n * const executeTask = defineCommandConsumer(taskQueue, tasksExchange, taskMessage);\n *\n * // Publishers send commands to it\n * const sendTask = defineCommandPublisher(executeTask);\n * ```\n */\nexport function defineCommandConsumer<\n  TMessage extends MessageDefinition,\n  TQueueEntry extends QueueEntry,\n  TExchange extends HeadersExchangeDefinition,\n>(\n  queue: TQueueEntry,\n  exchange: TExchange,\n  message: TMessage,\n  options?: {\n    arguments?: Record<string, unknown>;\n  },\n): CommandConsumerConfig<TMessage, TExchange, undefined, TQueueEntry>;\n\n/**\n * Define a command consumer for receiving commands via direct exchange.\n *\n * Commands are sent by publishers with a specific routing key that matches\n * the binding pattern.\n *\n * @param queue - The queue that will receive commands\n * @param exchange - The direct exchange that routes commands\n * @param message - The message definition (schema and metadata)\n * @param options - Configuration with required routing key\n * @param options.routingKey - The routing key for the binding\n * @param options.arguments - Additional AMQP arguments\n * @returns A command consumer configuration\n *\n * @example\n * ```typescript\n * const tasksExchange = defineExchange('tasks', { type: 'direct' });\n * const taskMessage = defineMessage(z.object({ taskId: z.string() }));\n *\n * const executeTask = defineCommandConsumer(taskQueue, tasksExchange, taskMessage, {\n *   routingKey: 'task.execute',\n * });\n *\n * const sendTask = defineCommandPublisher(executeTask);\n * ```\n */\nexport function defineCommandConsumer<\n  TMessage extends MessageDefinition,\n  TRoutingKey extends string,\n  TQueueEntry extends QueueEntry,\n  TExchange extends DirectExchangeDefinition,\n>(\n  queue: TQueueEntry,\n  exchange: TExchange,\n  message: TMessage,\n  options: {\n    routingKey: RoutingKey<TRoutingKey>;\n    arguments?: Record<string, unknown>;\n  },\n): CommandConsumerConfig<TMessage, TExchange, TRoutingKey, TQueueEntry>;\n\n/**\n * Define a command consumer for receiving commands via topic exchange.\n *\n * The consumer binds with a routing key pattern (can use * and # wildcards).\n * Publishers then send commands with concrete routing keys that match the pattern.\n *\n * @param queue - The queue that will receive commands\n * @param exchange - The topic exchange that routes commands\n * @param message - The message definition (schema and metadata)\n * @param options - Configuration with required routing key pattern\n * @param options.routingKey - The routing key pattern for the binding\n * @param options.arguments - Additional AMQP arguments\n * @returns A command consumer configuration\n *\n * @example\n * ```typescript\n * const ordersExchange = defineExchange('orders', { type: 'topic' });\n * const orderMessage = defineMessage(z.object({ orderId: z.string() }));\n *\n * // Consumer uses pattern to receive multiple command types\n * const processOrder = defineCommandConsumer(orderQueue, ordersExchange, orderMessage, {\n *   routingKey: 'order.*',\n * });\n *\n * // Publishers send with concrete keys\n * const createOrder = defineCommandPublisher(processOrder, {\n *   routingKey: 'order.create',\n * });\n * const updateOrder = defineCommandPublisher(processOrder, {\n *   routingKey: 'order.update',\n * });\n * ```\n */\nexport function defineCommandConsumer<\n  TMessage extends MessageDefinition,\n  TRoutingKey extends string,\n  TQueueEntry extends QueueEntry,\n  TExchange extends TopicExchangeDefinition,\n>(\n  queue: TQueueEntry,\n  exchange: TExchange,\n  message: TMessage,\n  options: {\n    routingKey: BindingPattern<TRoutingKey>;\n    arguments?: Record<string, unknown>;\n  },\n): CommandConsumerConfig<TMessage, TExchange, TRoutingKey, TQueueEntry>;\n\n/**\n * Implementation of defineCommandConsumer.\n * @internal\n */\nexport function defineCommandConsumer<TMessage extends MessageDefinition>(\n  queue: QueueEntry,\n  exchange: ExchangeDefinition,\n  message: TMessage,\n  options?: {\n    routingKey?: string;\n    arguments?: Record<string, unknown>;\n  },\n): CommandConsumerConfig<TMessage, ExchangeDefinition, string | undefined> {\n  const consumer = defineConsumer(queue, message);\n  const binding = defineQueueBindingInternal(queue, exchange, options);\n\n  return {\n    __brand: \"CommandConsumerConfig\",\n    consumer,\n    binding,\n    exchange,\n    queue,\n    message,\n    routingKey: options?.routingKey,\n  };\n}\n\n/**\n * Create a bridged publisher that sends commands to a fanout exchange consumer via a bridge exchange.\n *\n * @param commandConsumer - The command consumer configuration\n * @param options - Configuration with required bridgeExchange\n * @param options.bridgeExchange - The local domain exchange to bridge through (must be fanout to match target)\n * @returns A bridged publisher configuration\n */\nexport function defineCommandPublisher<\n  TMessage extends MessageDefinition,\n  TExchange extends FanoutExchangeDefinition,\n  TBridgeExchange extends FanoutExchangeDefinition,\n>(\n  commandConsumer: CommandConsumerConfig<TMessage, TExchange, undefined>,\n  options: {\n    bridgeExchange: TBridgeExchange;\n  },\n): BridgedPublisherConfig<TMessage, TBridgeExchange, TExchange>;\n\n/**\n * Create a bridged publisher that sends commands to a headers exchange consumer via a bridge exchange.\n *\n * @param commandConsumer - The command consumer configuration\n * @param options - Configuration with required bridgeExchange\n * @param options.bridgeExchange - The local domain exchange to bridge through (must be headers to match target)\n * @returns A bridged publisher configuration\n */\nexport function defineCommandPublisher<\n  TMessage extends MessageDefinition,\n  TExchange extends HeadersExchangeDefinition,\n  TBridgeExchange extends HeadersExchangeDefinition,\n>(\n  commandConsumer: CommandConsumerConfig<TMessage, TExchange, undefined>,\n  options: {\n    bridgeExchange: TBridgeExchange;\n  },\n): BridgedPublisherConfig<TMessage, TBridgeExchange, TExchange>;\n\n/**\n * Create a bridged publisher that sends commands to a direct exchange consumer via a bridge exchange.\n *\n * @param commandConsumer - The command consumer configuration\n * @param options - Configuration with required bridgeExchange\n * @param options.bridgeExchange - The bridge exchange (must be direct or topic to preserve routing keys)\n * @returns A bridged publisher configuration\n */\nexport function defineCommandPublisher<\n  TMessage extends MessageDefinition,\n  TRoutingKey extends string,\n  TExchange extends DirectExchangeDefinition,\n  TBridgeExchange extends DirectExchangeDefinition | TopicExchangeDefinition,\n>(\n  commandConsumer: CommandConsumerConfig<TMessage, TExchange, TRoutingKey>,\n  options: {\n    bridgeExchange: TBridgeExchange;\n  },\n): BridgedPublisherConfig<TMessage, TBridgeExchange, TExchange>;\n\n/**\n * Create a bridged publisher that sends commands to a topic exchange consumer via a bridge exchange.\n *\n * @param commandConsumer - The command consumer configuration\n * @param options - Configuration with required bridgeExchange and optional routingKey override\n * @param options.bridgeExchange - The bridge exchange (must be direct or topic to preserve routing keys)\n * @param options.routingKey - Override routing key (must match consumer's pattern)\n * @returns A bridged publisher configuration\n */\nexport function defineCommandPublisher<\n  TMessage extends MessageDefinition,\n  TRoutingKey extends string,\n  TExchange extends TopicExchangeDefinition,\n  TBridgeExchange extends DirectExchangeDefinition | TopicExchangeDefinition,\n  TPublisherRoutingKey extends string = TRoutingKey,\n>(\n  commandConsumer: CommandConsumerConfig<TMessage, TExchange, TRoutingKey>,\n  options: {\n    bridgeExchange: TBridgeExchange;\n    routingKey?: RoutingKey<TPublisherRoutingKey>;\n  },\n): BridgedPublisherConfig<TMessage, TBridgeExchange, TExchange>;\n\n/**\n * Create a publisher that sends commands to a fanout exchange consumer.\n *\n * @param commandConsumer - The command consumer configuration\n * @returns A publisher definition\n *\n * @example\n * ```typescript\n * const executeTask = defineCommandConsumer(taskQueue, fanoutExchange, taskMessage);\n * const sendTask = defineCommandPublisher(executeTask);\n * ```\n */\nexport function defineCommandPublisher<TMessage extends MessageDefinition>(\n  commandConsumer: CommandConsumerConfig<TMessage, FanoutExchangeDefinition, undefined>,\n): { message: TMessage; exchange: FanoutExchangeDefinition };\n\n/**\n * Create a publisher that sends commands to a headers exchange consumer.\n *\n * @param commandConsumer - The command consumer configuration\n * @returns A publisher definition\n *\n * @example\n * ```typescript\n * const executeTask = defineCommandConsumer(taskQueue, headersExchange, taskMessage);\n * const sendTask = defineCommandPublisher(executeTask);\n * ```\n */\nexport function defineCommandPublisher<TMessage extends MessageDefinition>(\n  commandConsumer: CommandConsumerConfig<TMessage, HeadersExchangeDefinition, undefined>,\n): { message: TMessage; exchange: HeadersExchangeDefinition };\n\n/**\n * Create a publisher that sends commands to a direct exchange consumer.\n *\n * @param commandConsumer - The command consumer configuration\n * @returns A publisher definition\n */\nexport function defineCommandPublisher<\n  TMessage extends MessageDefinition,\n  TRoutingKey extends string,\n>(\n  commandConsumer: CommandConsumerConfig<TMessage, DirectExchangeDefinition, TRoutingKey>,\n): { message: TMessage; exchange: DirectExchangeDefinition; routingKey: string };\n\n/**\n * Create a publisher that sends commands to a topic exchange consumer.\n *\n * For topic exchanges where the consumer uses a pattern, the publisher can\n * optionally specify a concrete routing key that matches the pattern.\n *\n * @param commandConsumer - The command consumer configuration\n * @param options - Optional binding configuration\n * @param options.routingKey - Override routing key (must match consumer's pattern)\n * @returns A publisher definition\n *\n * @example\n * ```typescript\n * // Consumer binds with pattern\n * const processOrder = defineCommandConsumer(orderQueue, topicExchange, orderMessage, {\n *   routingKey: 'order.*',\n * });\n *\n * // Publisher uses concrete key matching the pattern\n * const createOrder = defineCommandPublisher(processOrder, {\n *   routingKey: 'order.create',\n * });\n * ```\n */\nexport function defineCommandPublisher<\n  TMessage extends MessageDefinition,\n  TRoutingKey extends string,\n  TPublisherRoutingKey extends string = TRoutingKey,\n>(\n  commandConsumer: CommandConsumerConfig<TMessage, TopicExchangeDefinition, TRoutingKey>,\n  options?: {\n    routingKey?: RoutingKey<TPublisherRoutingKey>;\n  },\n): { message: TMessage; exchange: TopicExchangeDefinition; routingKey: string };\n\n/**\n * Implementation of defineCommandPublisher.\n * @internal\n */\nexport function defineCommandPublisher<TMessage extends MessageDefinition>(\n  commandConsumer: CommandConsumerConfig<TMessage, ExchangeDefinition, string | undefined>,\n  options?: {\n    routingKey?: string;\n    bridgeExchange?: ExchangeDefinition;\n  },\n):\n  | PublisherDefinition<TMessage>\n  | BridgedPublisherConfig<TMessage, ExchangeDefinition, ExchangeDefinition> {\n  const { exchange: targetExchange, message, routingKey: consumerRoutingKey } = commandConsumer;\n\n  // For topic exchanges, publisher can override the routing key\n  const publisherRoutingKey = options?.routingKey ?? consumerRoutingKey;\n\n  const bridgeExchange = options?.bridgeExchange;\n\n  if (bridgeExchange) {\n    // Bridged: publisher publishes to bridge exchange, e2e binding from bridge → target\n    const publisherOptions: { routingKey?: string } = {};\n    if (publisherRoutingKey !== undefined) {\n      publisherOptions.routingKey = publisherRoutingKey;\n    }\n\n    const publisher = definePublisherInternal(bridgeExchange, message, publisherOptions);\n\n    // Create e2e binding: target ← bridge (destination = target, source = bridge)\n    const e2eBindingOptions: { routingKey?: string } = {};\n    if (publisherRoutingKey !== undefined) {\n      e2eBindingOptions.routingKey = publisherRoutingKey;\n    }\n    const e2eBinding =\n      bridgeExchange.type === \"fanout\" || bridgeExchange.type === \"headers\"\n        ? defineExchangeBinding(targetExchange, bridgeExchange)\n        : defineExchangeBinding(\n            targetExchange,\n            bridgeExchange as DirectExchangeDefinition | TopicExchangeDefinition,\n            e2eBindingOptions as { routingKey: string },\n          );\n\n    return {\n      __brand: \"BridgedPublisherConfig\",\n      publisher,\n      exchangeBinding: e2eBinding,\n      bridgeExchange,\n      targetExchange,\n    };\n  }\n\n  const publisherOptions: { routingKey?: string } = {};\n  if (publisherRoutingKey !== undefined) {\n    publisherOptions.routingKey = publisherRoutingKey;\n  }\n\n  return definePublisherInternal(targetExchange, message, publisherOptions);\n}\n\n/**\n * Type guard to check if a value is a CommandConsumerConfig.\n *\n * @param value - The value to check\n * @returns True if the value is a CommandConsumerConfig\n */\nexport function isCommandConsumerConfig(\n  value: unknown,\n): value is CommandConsumerConfig<MessageDefinition, ExchangeDefinition, string | undefined> {\n  return (\n    typeof value === \"object\" &&\n    value !== null &&\n    \"__brand\" in value &&\n    value.__brand === \"CommandConsumerConfig\"\n  );\n}\n\n/**\n * Type guard to check if a value is a BridgedPublisherConfig.\n *\n * @param value - The value to check\n * @returns True if the value is a BridgedPublisherConfig\n */\nexport function isBridgedPublisherConfig(\n  value: unknown,\n): value is BridgedPublisherConfig<MessageDefinition, ExchangeDefinition, ExchangeDefinition> {\n  return (\n    typeof value === \"object\" &&\n    value !== null &&\n    \"__brand\" in value &&\n    value.__brand === \"BridgedPublisherConfig\"\n  );\n}\n","import type {\n  ConsumerDefinition,\n  DirectExchangeDefinition,\n  ExchangeBindingDefinition,\n  ExchangeDefinition,\n  FanoutExchangeDefinition,\n  HeadersExchangeDefinition,\n  MessageDefinition,\n  QueueBindingDefinition,\n  QueueEntry,\n  TopicExchangeDefinition,\n} from \"../types.js\";\nimport { defineExchangeBinding, defineQueueBindingInternal } from \"./binding.js\";\nimport { defineConsumer } from \"./consumer.js\";\nimport type { BindingPattern, RoutingKey } from \"./routing-types.js\";\n\n/**\n * Configuration for an event publisher.\n *\n * Events are published without knowing who consumes them. Multiple consumers\n * can subscribe to the same event. This follows the pub/sub pattern where\n * publishers broadcast events and consumers subscribe to receive them.\n *\n * @template TMessage - The message definition\n * @template TExchange - The exchange definition\n * @template TRoutingKey - The routing key type (undefined for fanout and headers exchanges)\n */\nexport type EventPublisherConfig<\n  TMessage extends MessageDefinition,\n  TExchange extends ExchangeDefinition,\n  TRoutingKey extends string | undefined = undefined,\n> = {\n  /** Discriminator to identify this as an event publisher config */\n  __brand: \"EventPublisherConfig\";\n  /** The exchange to publish to */\n  exchange: TExchange;\n  /** The message definition */\n  message: TMessage;\n  /** The routing key for direct/topic exchanges */\n  routingKey: TRoutingKey;\n  /** Additional AMQP arguments */\n  arguments?: Record<string, unknown>;\n};\n\n/**\n * Result from defineEventConsumer.\n *\n * Contains the consumer definition and binding needed to subscribe to an event.\n * Can be used directly in defineContract's consumers section - the binding\n * will be automatically extracted.\n *\n * @template TMessage - The message definition\n */\nexport type EventConsumerResult<\n  TMessage extends MessageDefinition,\n  TExchange extends ExchangeDefinition = ExchangeDefinition,\n  TQueue extends QueueEntry = QueueEntry,\n  TExchangeBinding extends ExchangeBindingDefinition | undefined =\n    | ExchangeBindingDefinition\n    | undefined,\n  TBridgeExchange extends ExchangeDefinition | undefined = ExchangeDefinition | undefined,\n> = {\n  /** Discriminator to identify this as an event consumer result */\n  __brand: \"EventConsumerResult\";\n  /** The consumer definition for processing messages */\n  consumer: ConsumerDefinition<TMessage>;\n  /** The binding connecting the queue to the exchange */\n  binding: QueueBindingDefinition;\n  /** The source exchange this consumer subscribes to */\n  exchange: TExchange;\n  /** The queue this consumer reads from */\n  queue: TQueue;\n  /** The exchange-to-exchange binding when bridging, if configured */\n  exchangeBinding: TExchangeBinding;\n  /** The bridge (local domain) exchange when bridging, if configured */\n  bridgeExchange: TBridgeExchange;\n};\n\n/**\n * Define an event publisher for broadcasting messages via fanout exchange.\n *\n * Events are published without knowing who consumes them. Multiple consumers\n * can subscribe to the same event using `defineEventConsumer`.\n *\n * @param exchange - The fanout exchange to publish to\n * @param message - The message definition (schema and metadata)\n * @param options - Optional binding configuration\n * @param options.arguments - Additional AMQP arguments\n * @returns An event publisher configuration\n *\n * @example\n * ```typescript\n * const logsExchange = defineExchange('logs', { type: 'fanout' });\n * const logMessage = defineMessage(z.object({\n *   level: z.enum(['info', 'warn', 'error']),\n *   message: z.string(),\n * }));\n *\n * // Create event publisher\n * const logEvent = defineEventPublisher(logsExchange, logMessage);\n *\n * // Multiple consumers can subscribe\n * const { consumer: fileConsumer, binding: fileBinding } =\n *   defineEventConsumer(logEvent, fileLogsQueue);\n * const { consumer: alertConsumer, binding: alertBinding } =\n *   defineEventConsumer(logEvent, alertsQueue);\n * ```\n */\nexport function defineEventPublisher<\n  TMessage extends MessageDefinition,\n  TExchange extends FanoutExchangeDefinition,\n>(\n  exchange: TExchange,\n  message: TMessage,\n  options?: {\n    arguments?: Record<string, unknown>;\n  },\n): EventPublisherConfig<TMessage, TExchange, undefined>;\n\n/**\n * Define an event publisher for broadcasting messages via headers exchange.\n *\n * Events are published without knowing who consumes them. Multiple consumers\n * can subscribe to the same event using `defineEventConsumer`.\n *\n * @param exchange - The headers exchange to publish to\n * @param message - The message definition (schema and metadata)\n * @param options - Optional binding configuration\n * @param options.arguments - Additional AMQP arguments\n * @returns An event publisher configuration\n *\n * @example\n * ```typescript\n * const logsExchange = defineExchange('logs', { type: 'headers' });\n * const logMessage = defineMessage(z.object({\n *   level: z.enum(['info', 'warn', 'error']),\n *   message: z.string(),\n * }));\n *\n * // Create event publisher\n * const logEvent = defineEventPublisher(logsExchange, logMessage);\n *\n * // Multiple consumers can subscribe\n * const { consumer: fileConsumer, binding: fileBinding } =\n *   defineEventConsumer(logEvent, fileLogsQueue);\n * const { consumer: alertConsumer, binding: alertBinding } =\n *   defineEventConsumer(logEvent, alertsQueue);\n * ```\n */\nexport function defineEventPublisher<\n  TMessage extends MessageDefinition,\n  TExchange extends HeadersExchangeDefinition,\n>(\n  exchange: TExchange,\n  message: TMessage,\n  options?: {\n    arguments?: Record<string, unknown>;\n  },\n): EventPublisherConfig<TMessage, TExchange, undefined>;\n\n/**\n * Define an event publisher for broadcasting messages via direct exchange.\n *\n * Events are published with a specific routing key. Consumers will receive\n * messages that match the routing key exactly.\n *\n * @param exchange - The direct exchange to publish to\n * @param message - The message definition (schema and metadata)\n * @param options - Configuration with required routing key\n * @param options.routingKey - The routing key for message routing\n * @param options.arguments - Additional AMQP arguments\n * @returns An event publisher configuration\n *\n * @example\n * ```typescript\n * const tasksExchange = defineExchange('tasks', { type: 'direct' });\n * const taskMessage = defineMessage(z.object({ taskId: z.string() }));\n *\n * const taskEvent = defineEventPublisher(tasksExchange, taskMessage, {\n *   routingKey: 'task.execute',\n * });\n * ```\n */\nexport function defineEventPublisher<\n  TMessage extends MessageDefinition,\n  TRoutingKey extends string,\n  TExchange extends DirectExchangeDefinition,\n>(\n  exchange: TExchange,\n  message: TMessage,\n  options: {\n    routingKey: RoutingKey<TRoutingKey>;\n    arguments?: Record<string, unknown>;\n  },\n): EventPublisherConfig<TMessage, TExchange, TRoutingKey>;\n\n/**\n * Define an event publisher for broadcasting messages via topic exchange.\n *\n * Events are published with a concrete routing key. Consumers can subscribe\n * using patterns (with * and # wildcards) to receive matching messages.\n *\n * @param exchange - The topic exchange to publish to\n * @param message - The message definition (schema and metadata)\n * @param options - Configuration with required routing key\n * @param options.routingKey - The concrete routing key (no wildcards)\n * @param options.arguments - Additional AMQP arguments\n * @returns An event publisher configuration\n *\n * @example\n * ```typescript\n * const ordersExchange = defineExchange('orders', { type: 'topic' });\n * const orderMessage = defineMessage(z.object({\n *   orderId: z.string(),\n *   amount: z.number(),\n * }));\n *\n * // Publisher uses concrete routing key\n * const orderCreatedEvent = defineEventPublisher(ordersExchange, orderMessage, {\n *   routingKey: 'order.created',\n * });\n *\n * // Consumer can use pattern\n * const { consumer, binding } = defineEventConsumer(\n *   orderCreatedEvent,\n *   allOrdersQueue,\n *   { routingKey: 'order.*' },\n * );\n * ```\n */\nexport function defineEventPublisher<\n  TMessage extends MessageDefinition,\n  TRoutingKey extends string,\n  TExchange extends TopicExchangeDefinition,\n>(\n  exchange: TExchange,\n  message: TMessage,\n  options: {\n    routingKey: RoutingKey<TRoutingKey>;\n    arguments?: Record<string, unknown>;\n  },\n): EventPublisherConfig<TMessage, TExchange, TRoutingKey>;\n\n/**\n * Implementation of defineEventPublisher.\n * @internal\n */\nexport function defineEventPublisher<TMessage extends MessageDefinition>(\n  exchange: ExchangeDefinition,\n  message: TMessage,\n  options?: {\n    routingKey?: string;\n    arguments?: Record<string, unknown>;\n  },\n): EventPublisherConfig<TMessage, ExchangeDefinition, string | undefined> {\n  const config: EventPublisherConfig<TMessage, ExchangeDefinition, string | undefined> = {\n    __brand: \"EventPublisherConfig\",\n    exchange,\n    message,\n    routingKey: options?.routingKey,\n  };\n\n  if (options?.arguments !== undefined) {\n    config.arguments = options.arguments;\n  }\n\n  return config;\n}\n\n/**\n * Create a consumer that subscribes to an event from a fanout exchange via a bridge exchange.\n *\n * When `bridgeExchange` is provided, the queue binds to the bridge exchange instead of the\n * source exchange, and an exchange-to-exchange binding is created from the source to the bridge.\n *\n * @param eventPublisher - The event publisher configuration\n * @param queue - The queue that will receive messages\n * @param options - Binding configuration with required bridgeExchange\n * @param options.bridgeExchange - The fanout bridge exchange (must be fanout to match source)\n * @param options.arguments - Additional AMQP arguments\n * @returns An object with the consumer definition, queue binding, and exchange binding\n */\nexport function defineEventConsumer<\n  TMessage extends MessageDefinition,\n  TExchange extends FanoutExchangeDefinition,\n  TQueueEntry extends QueueEntry,\n  TBridgeExchange extends FanoutExchangeDefinition,\n>(\n  eventPublisher: EventPublisherConfig<TMessage, TExchange, undefined>,\n  queue: TQueueEntry,\n  options: {\n    bridgeExchange: TBridgeExchange;\n    arguments?: Record<string, unknown>;\n  },\n): EventConsumerResult<\n  TMessage,\n  TExchange,\n  TQueueEntry,\n  ExchangeBindingDefinition,\n  TBridgeExchange\n>;\n\n/**\n * Create a consumer that subscribes to an event from a headers exchange via a bridge exchange.\n *\n * When `bridgeExchange` is provided, the queue binds to the bridge exchange instead of the\n * source exchange, and an exchange-to-exchange binding is created from the source to the bridge.\n *\n * @param eventPublisher - The event publisher configuration\n * @param queue - The queue that will receive messages\n * @param options - Binding configuration with required bridgeExchange\n * @param options.bridgeExchange - The headers bridge exchange (must be headers to match source)\n * @param options.arguments - Additional AMQP arguments\n * @returns An object with the consumer definition, queue binding, and exchange binding\n */\nexport function defineEventConsumer<\n  TMessage extends MessageDefinition,\n  TExchange extends HeadersExchangeDefinition,\n  TQueueEntry extends QueueEntry,\n  TBridgeExchange extends HeadersExchangeDefinition,\n>(\n  eventPublisher: EventPublisherConfig<TMessage, TExchange, undefined>,\n  queue: TQueueEntry,\n  options: {\n    bridgeExchange: TBridgeExchange;\n    arguments?: Record<string, unknown>;\n  },\n): EventConsumerResult<\n  TMessage,\n  TExchange,\n  TQueueEntry,\n  ExchangeBindingDefinition,\n  TBridgeExchange\n>;\n\n/**\n * Create a consumer that subscribes to an event from a direct exchange via a bridge exchange.\n *\n * @param eventPublisher - The event publisher configuration\n * @param queue - The queue that will receive messages\n * @param options - Binding configuration with required bridgeExchange\n * @param options.bridgeExchange - The bridge exchange (must be direct or topic to preserve routing keys)\n * @param options.arguments - Additional AMQP arguments\n * @returns An object with the consumer definition, queue binding, and exchange binding\n */\nexport function defineEventConsumer<\n  TMessage extends MessageDefinition,\n  TRoutingKey extends string,\n  TExchange extends DirectExchangeDefinition,\n  TQueueEntry extends QueueEntry,\n  TBridgeExchange extends DirectExchangeDefinition | TopicExchangeDefinition,\n>(\n  eventPublisher: EventPublisherConfig<TMessage, TExchange, TRoutingKey>,\n  queue: TQueueEntry,\n  options: {\n    bridgeExchange: TBridgeExchange;\n    arguments?: Record<string, unknown>;\n  },\n): EventConsumerResult<\n  TMessage,\n  TExchange,\n  TQueueEntry,\n  ExchangeBindingDefinition,\n  TBridgeExchange\n>;\n\n/**\n * Create a consumer that subscribes to an event from a topic exchange via a bridge exchange.\n *\n * @param eventPublisher - The event publisher configuration\n * @param queue - The queue that will receive messages\n * @param options - Binding configuration with required bridgeExchange\n * @param options.bridgeExchange - The bridge exchange (must be direct or topic to preserve routing keys)\n * @param options.routingKey - Override routing key with pattern (defaults to publisher's key)\n * @param options.arguments - Additional AMQP arguments\n * @returns An object with the consumer definition, queue binding, and exchange binding\n */\nexport function defineEventConsumer<\n  TMessage extends MessageDefinition,\n  TRoutingKey extends string,\n  TExchange extends TopicExchangeDefinition,\n  TQueueEntry extends QueueEntry,\n  TBridgeExchange extends DirectExchangeDefinition | TopicExchangeDefinition,\n  TConsumerRoutingKey extends string = TRoutingKey,\n>(\n  eventPublisher: EventPublisherConfig<TMessage, TExchange, TRoutingKey>,\n  queue: TQueueEntry,\n  options: {\n    bridgeExchange: TBridgeExchange;\n    routingKey?: BindingPattern<TConsumerRoutingKey>;\n    arguments?: Record<string, unknown>;\n  },\n): EventConsumerResult<\n  TMessage,\n  TExchange,\n  TQueueEntry,\n  ExchangeBindingDefinition,\n  TBridgeExchange\n>;\n\n/**\n * Create a consumer that subscribes to an event from a fanout exchange.\n *\n * @param eventPublisher - The event publisher configuration\n * @param queue - The queue that will receive messages\n * @param options - Optional binding configuration\n * @param options.arguments - Additional AMQP arguments\n * @returns An object with the consumer definition and binding\n *\n * @example\n * ```typescript\n * const logEvent = defineEventPublisher(logsExchange, logMessage);\n * const { consumer, binding } = defineEventConsumer(logEvent, logsQueue);\n * ```\n */\nexport function defineEventConsumer<\n  TMessage extends MessageDefinition,\n  TExchange extends FanoutExchangeDefinition,\n  TQueueEntry extends QueueEntry,\n>(\n  eventPublisher: EventPublisherConfig<TMessage, TExchange, undefined>,\n  queue: TQueueEntry,\n  options?: {\n    arguments?: Record<string, unknown>;\n  },\n): EventConsumerResult<TMessage, TExchange, TQueueEntry>;\n\n/**\n * Create a consumer that subscribes to an event from a headers exchange.\n *\n * @param eventPublisher - The event publisher configuration\n * @param queue - The queue that will receive messages\n * @param options - Optional binding configuration\n * @param options.arguments - Additional AMQP arguments\n * @returns An object with the consumer definition and binding\n *\n * @example\n * ```typescript\n * const logEvent = defineEventPublisher(logsExchange, logMessage);\n * const { consumer, binding } = defineEventConsumer(logEvent, logsQueue);\n * ```\n */\nexport function defineEventConsumer<\n  TMessage extends MessageDefinition,\n  TExchange extends HeadersExchangeDefinition,\n  TQueueEntry extends QueueEntry,\n>(\n  eventPublisher: EventPublisherConfig<TMessage, TExchange, undefined>,\n  queue: TQueueEntry,\n  options?: {\n    arguments?: Record<string, unknown>;\n  },\n): EventConsumerResult<TMessage, TExchange, TQueueEntry>;\n\n/**\n * Create a consumer that subscribes to an event from a direct exchange.\n *\n * @param eventPublisher - The event publisher configuration\n * @param queue - The queue that will receive messages\n * @param options - Optional binding configuration\n * @param options.arguments - Additional AMQP arguments\n * @returns An object with the consumer definition and binding\n */\nexport function defineEventConsumer<\n  TMessage extends MessageDefinition,\n  TRoutingKey extends string,\n  TExchange extends DirectExchangeDefinition,\n  TQueueEntry extends QueueEntry,\n>(\n  eventPublisher: EventPublisherConfig<TMessage, TExchange, TRoutingKey>,\n  queue: TQueueEntry,\n  options?: {\n    arguments?: Record<string, unknown>;\n  },\n): EventConsumerResult<TMessage, TExchange, TQueueEntry>;\n\n/**\n * Create a consumer that subscribes to an event from a topic exchange.\n *\n * For topic exchanges, the consumer can optionally override the routing key\n * with a pattern to subscribe to multiple events.\n *\n * @param eventPublisher - The event publisher configuration\n * @param queue - The queue that will receive messages\n * @param options - Optional binding configuration\n * @param options.routingKey - Override routing key with pattern (defaults to publisher's key)\n * @param options.arguments - Additional AMQP arguments\n * @returns An object with the consumer definition and binding\n *\n * @example\n * ```typescript\n * const orderCreatedEvent = defineEventPublisher(ordersExchange, orderMessage, {\n *   routingKey: 'order.created',\n * });\n *\n * // Use exact routing key from publisher\n * const { consumer: exactConsumer } = defineEventConsumer(orderCreatedEvent, exactQueue);\n *\n * // Override with pattern to receive all order events\n * const { consumer: allConsumer } = defineEventConsumer(orderCreatedEvent, allQueue, {\n *   routingKey: 'order.*',\n * });\n * ```\n */\nexport function defineEventConsumer<\n  TMessage extends MessageDefinition,\n  TRoutingKey extends string,\n  TExchange extends TopicExchangeDefinition,\n  TQueueEntry extends QueueEntry,\n  TConsumerRoutingKey extends string = TRoutingKey,\n>(\n  eventPublisher: EventPublisherConfig<TMessage, TExchange, TRoutingKey>,\n  queue: TQueueEntry,\n  options?: {\n    routingKey?: BindingPattern<TConsumerRoutingKey>;\n    arguments?: Record<string, unknown>;\n  },\n): EventConsumerResult<TMessage, TExchange, TQueueEntry>;\n\n/**\n * Implementation of defineEventConsumer.\n * @internal\n */\nexport function defineEventConsumer<TMessage extends MessageDefinition>(\n  eventPublisher: EventPublisherConfig<TMessage, ExchangeDefinition, string | undefined>,\n  queue: QueueEntry,\n  options?: {\n    routingKey?: string;\n    bridgeExchange?: ExchangeDefinition;\n    arguments?: Record<string, unknown>;\n  },\n): EventConsumerResult<TMessage> {\n  const { exchange: sourceExchange, message, routingKey: publisherRoutingKey } = eventPublisher;\n\n  // For topic exchanges, consumer can override the routing key\n  const bindingRoutingKey = options?.routingKey ?? publisherRoutingKey;\n\n  const bindingOptions: { routingKey?: string; arguments?: Record<string, unknown> } = {};\n  if (bindingRoutingKey !== undefined) {\n    bindingOptions.routingKey = bindingRoutingKey;\n  }\n  const bindingArguments = options?.arguments ?? eventPublisher.arguments;\n  if (bindingArguments !== undefined) {\n    bindingOptions.arguments = bindingArguments;\n  }\n\n  const bridgeExchange = options?.bridgeExchange;\n\n  if (bridgeExchange) {\n    // Bridged: queue binds to bridge exchange, e2e binding from source → bridge\n    const binding = defineQueueBindingInternal(queue, bridgeExchange, bindingOptions);\n    const consumer = defineConsumer(queue, message);\n\n    // Create e2e binding: bridge ← source (destination ← source)\n    const exchangeBindingOptions: { routingKey?: string } = {};\n    if (bindingRoutingKey !== undefined) {\n      exchangeBindingOptions.routingKey = bindingRoutingKey;\n    }\n    const e2eBinding =\n      sourceExchange.type === \"fanout\" || sourceExchange.type === \"headers\"\n        ? defineExchangeBinding(bridgeExchange, sourceExchange)\n        : defineExchangeBinding(\n            bridgeExchange,\n            sourceExchange as DirectExchangeDefinition | TopicExchangeDefinition,\n            exchangeBindingOptions as { routingKey: string },\n          );\n\n    return {\n      __brand: \"EventConsumerResult\",\n      consumer,\n      binding,\n      exchange: sourceExchange,\n      queue,\n      exchangeBinding: e2eBinding,\n      bridgeExchange,\n    } as EventConsumerResult<TMessage>;\n  }\n\n  const binding = defineQueueBindingInternal(queue, sourceExchange, bindingOptions);\n  const consumer = defineConsumer(queue, message);\n\n  return {\n    __brand: \"EventConsumerResult\",\n    consumer,\n    binding,\n    exchange: sourceExchange,\n    queue,\n    exchangeBinding: undefined,\n    bridgeExchange: undefined,\n  };\n}\n\n/**\n * Type guard to check if a value is an EventPublisherConfig.\n *\n * @param value - The value to check\n * @returns True if the value is an EventPublisherConfig\n */\nexport function isEventPublisherConfig(\n  value: unknown,\n): value is EventPublisherConfig<MessageDefinition, ExchangeDefinition, string | undefined> {\n  return (\n    typeof value === \"object\" &&\n    value !== null &&\n    \"__brand\" in value &&\n    value.__brand === \"EventPublisherConfig\"\n  );\n}\n\n/**\n * Type guard to check if a value is an EventConsumerResult.\n *\n * @param value - The value to check\n * @returns True if the value is an EventConsumerResult\n */\nexport function isEventConsumerResult(\n  value: unknown,\n): value is EventConsumerResult<MessageDefinition> {\n  return (\n    typeof value === \"object\" &&\n    value !== null &&\n    \"__brand\" in value &&\n    value.__brand === \"EventConsumerResult\"\n  );\n}\n","import type {\n  BindingDefinition,\n  ConsumerDefinition,\n  ContractDefinition,\n  ContractDefinitionInput,\n  ContractOutput,\n  ExchangeDefinition,\n  PublisherDefinition,\n  QueueEntry,\n  RpcDefinition,\n} from \"../types.js\";\nimport { isBridgedPublisherConfig, isCommandConsumerConfig } from \"./command.js\";\nimport { isEventConsumerResult, isEventPublisherConfig } from \"./event.js\";\nimport { definePublisherInternal } from \"./publisher.js\";\nimport { extractQueue } from \"./queue-utils.js\";\nimport { isQueueWithTtlBackoffInfrastructure } from \"./ttl-backoff.js\";\n\n/**\n * Structural equality for resource definitions. We compare on a JSON projection\n * after stripping non-comparable fields (Standard Schema instances, branded\n * symbols) so that, e.g., two `defineExchange(\"orders\")` calls in different\n * files are treated as the same exchange.\n */\nfunction resourcesEqual(a: unknown, b: unknown): boolean {\n  if (a === b) return true;\n  try {\n    return JSON.stringify(a, replacer) === JSON.stringify(b, replacer);\n  } catch {\n    return false;\n  }\n}\n\nfunction replacer(_key: string, value: unknown): unknown {\n  // Standard Schema validators are functions / proxies that JSON.stringify\n  // cannot meaningfully compare. Reduce them to a structural marker so two\n  // independent `defineMessage(z.object({...}))` declarations of the same\n  // shape don't trip the collision check.\n  if (typeof value === \"function\") return \"[function]\";\n  if (value && typeof value === \"object\" && \"~standard\" in (value as object)) {\n    return \"[standard-schema]\";\n  }\n  return value;\n}\n\n/**\n * Add an entry to a name-keyed map, throwing if the name is already taken by a\n * structurally-different definition. Identical re-declarations are silently\n * deduplicated — that's how the same exchange can flow into the contract via\n * both a publisher and a consumer.\n */\nfunction addResource<T>(\n  bucket: Record<string, T>,\n  name: string,\n  value: T,\n  kind: \"exchange\" | \"queue\" | \"binding\",\n): void {\n  const existing = bucket[name];\n  if (existing === undefined) {\n    bucket[name] = value;\n    return;\n  }\n  if (!resourcesEqual(existing, value)) {\n    throw new Error(\n      `defineContract: ${kind} \"${name}\" was declared with conflicting definitions. ` +\n        `Two ${kind}s sharing a name must be the exact same definition; ` +\n        `define the ${kind} once and reference it from every publisher/consumer that needs it.`,\n    );\n  }\n}\n\n/**\n * Define an AMQP contract.\n *\n * A contract is the central definition of your AMQP messaging topology. It brings together\n * publishers and consumers in a single, type-safe definition. Exchanges, queues, and bindings\n * are automatically extracted from publishers and consumers.\n *\n * The contract is used by both clients (for publishing) and workers (for consuming) to ensure\n * type safety throughout your messaging infrastructure. TypeScript will infer all message types\n * and publisher/consumer names from the contract.\n *\n * @param definition - The contract definition containing publishers and consumers\n * @param definition.publishers - Named publisher definitions for sending messages\n * @param definition.consumers - Named consumer definitions for receiving messages\n * @returns The contract definition with fully inferred exchanges, queues, bindings, publishers, and consumers\n *\n * @example\n * ```typescript\n * import {\n *   defineContract,\n *   defineExchange,\n *   defineQueue,\n *   defineEventPublisher,\n *   defineEventConsumer,\n *   defineMessage,\n * } from '@amqp-contract/contract';\n * import { z } from 'zod';\n *\n * // Define resources\n * const ordersExchange = defineExchange('orders');\n * const dlx = defineExchange('orders-dlx', { type: 'direct' });\n * const orderQueue = defineQueue('order-processing', {\n *   deadLetter: { exchange: dlx },\n *   retry: { mode: 'immediate-requeue', maxRetries: 3 },\n * });\n * const orderMessage = defineMessage(\n *   z.object({\n *     orderId: z.string(),\n *     amount: z.number(),\n *   })\n * );\n *\n * // Define event publisher\n * const orderCreatedEvent = defineEventPublisher(ordersExchange, orderMessage, {\n *   routingKey: 'order.created',\n * });\n *\n * // Compose contract - exchanges, queues, bindings are auto-extracted\n * export const contract = defineContract({\n *   publishers: {\n *     orderCreated: orderCreatedEvent,\n *   },\n *   consumers: {\n *     processOrder: defineEventConsumer(orderCreatedEvent, orderQueue),\n *   },\n * });\n *\n * // TypeScript now knows:\n * // - contract.exchanges.orders, contract.exchanges['orders-dlx']\n * // - contract.queues['order-processing']\n * // - contract.bindings.processOrderBinding\n * // - client.publish('orderCreated', { orderId: string, amount: number })\n * // - handler: (message: { orderId: string, amount: number }) => Future<Result<void, HandlerError>>\n * ```\n */\nexport function defineContract<TContract extends ContractDefinitionInput>(\n  definition: TContract,\n): ContractOutput<TContract> {\n  const { publishers: inputPublishers, consumers: inputConsumers, rpcs: inputRpcs } = definition;\n\n  // Consumer names and RPC names share the worker handler keyspace; if the\n  // same key appeared in both, the worker would consume from two queues under\n  // one name and dispatch ambiguously. Fail fast at contract-definition time\n  // rather than producing surprising runtime behavior.\n  if (inputConsumers && inputRpcs) {\n    const collisions = Object.keys(inputConsumers).filter((name) => Object.hasOwn(inputRpcs, name));\n    if (collisions.length > 0) {\n      throw new Error(\n        `defineContract: name collision between consumers and rpcs — keys must be disjoint. Conflicting names: ${collisions.join(\", \")}`,\n      );\n    }\n  }\n\n  const result: ContractDefinition = {\n    exchanges: {},\n    queues: {},\n    bindings: {},\n    publishers: {},\n    consumers: {},\n    rpcs: {},\n  };\n\n  const exchanges: Record<string, ExchangeDefinition> = {};\n  const queues: Record<string, QueueEntry> = {};\n  const bindings: Record<string, BindingDefinition> = {};\n\n  // Process publishers section - extract exchanges and convert EventPublisherConfig entries\n  if (inputPublishers && Object.keys(inputPublishers).length > 0) {\n    const processedPublishers: Record<string, PublisherDefinition> = {};\n\n    for (const [name, entry] of Object.entries(inputPublishers)) {\n      if (isBridgedPublisherConfig(entry)) {\n        // BridgedPublisherConfig: extract publisher, exchanges, and e2e binding\n        addResource(exchanges, entry.bridgeExchange.name, entry.bridgeExchange, \"exchange\");\n        addResource(exchanges, entry.targetExchange.name, entry.targetExchange, \"exchange\");\n        addResource(bindings, `${name}ExchangeBinding`, entry.exchangeBinding, \"binding\");\n        processedPublishers[name] = entry.publisher;\n      } else if (isEventPublisherConfig(entry)) {\n        // EventPublisherConfig: extract exchange and convert to publisher definition\n        addResource(exchanges, entry.exchange.name, entry.exchange, \"exchange\");\n        const publisherOptions: { routingKey?: string } = {};\n        if (entry.routingKey !== undefined) {\n          publisherOptions.routingKey = entry.routingKey;\n        }\n        processedPublishers[name] = definePublisherInternal(\n          entry.exchange,\n          entry.message,\n          publisherOptions,\n        );\n      } else {\n        // Plain PublisherDefinition: extract exchange\n        const publisher = entry as PublisherDefinition;\n        addResource(exchanges, publisher.exchange.name, publisher.exchange, \"exchange\");\n        processedPublishers[name] = publisher;\n      }\n    }\n\n    result.publishers = processedPublishers;\n  }\n\n  // Process consumers section - extract queues, exchanges, bindings, and consumer definitions\n  if (inputConsumers && Object.keys(inputConsumers).length > 0) {\n    const processedConsumers: Record<string, ConsumerDefinition> = {};\n    const consumerQueueEntries: QueueEntry[] = [];\n\n    for (const [name, entry] of Object.entries(inputConsumers)) {\n      if (isEventConsumerResult(entry)) {\n        // EventConsumerResult: extract consumer, binding, queue, and exchange\n        processedConsumers[name] = entry.consumer;\n        addResource(bindings, `${name}Binding`, entry.binding, \"binding\");\n\n        const queueEntry = entry.consumer.queue;\n        const queueDef = extractQueue(queueEntry);\n        addResource(queues, queueDef.name, queueEntry, \"queue\");\n        consumerQueueEntries.push(queueEntry);\n\n        addResource(exchanges, entry.binding.exchange.name, entry.binding.exchange, \"exchange\");\n\n        if (queueDef.deadLetter?.exchange) {\n          addResource(\n            exchanges,\n            queueDef.deadLetter.exchange.name,\n            queueDef.deadLetter.exchange,\n            \"exchange\",\n          );\n        }\n\n        if (entry.exchangeBinding) {\n          addResource(bindings, `${name}ExchangeBinding`, entry.exchangeBinding, \"binding\");\n        }\n        if (entry.bridgeExchange) {\n          addResource(exchanges, entry.bridgeExchange.name, entry.bridgeExchange, \"exchange\");\n        }\n        // Source exchange (stored in entry.exchange for bridged consumers)\n        if (entry.exchange) {\n          addResource(exchanges, entry.exchange.name, entry.exchange, \"exchange\");\n        }\n      } else if (isCommandConsumerConfig(entry)) {\n        // CommandConsumerConfig: extract consumer, binding, queue, and exchange\n        processedConsumers[name] = entry.consumer;\n        addResource(bindings, `${name}Binding`, entry.binding, \"binding\");\n\n        const queueEntry = entry.consumer.queue;\n        const queueDef = extractQueue(queueEntry);\n        addResource(queues, queueDef.name, queueEntry, \"queue\");\n        consumerQueueEntries.push(queueEntry);\n\n        addResource(exchanges, entry.exchange.name, entry.exchange, \"exchange\");\n\n        if (queueDef.deadLetter?.exchange) {\n          addResource(\n            exchanges,\n            queueDef.deadLetter.exchange.name,\n            queueDef.deadLetter.exchange,\n            \"exchange\",\n          );\n        }\n      } else {\n        // Plain ConsumerDefinition: extract queue\n        const consumer = entry as ConsumerDefinition;\n        processedConsumers[name] = consumer;\n\n        const queueEntry = consumer.queue;\n        const queueDef = extractQueue(queueEntry);\n        addResource(queues, queueDef.name, queueEntry, \"queue\");\n        consumerQueueEntries.push(queueEntry);\n\n        if (queueDef.deadLetter?.exchange) {\n          addResource(\n            exchanges,\n            queueDef.deadLetter.exchange.name,\n            queueDef.deadLetter.exchange,\n            \"exchange\",\n          );\n        }\n      }\n    }\n\n    // Auto-generate TTL-backoff retry infrastructure for queues with TTL-backoff retry mode\n    for (const queueEntry of consumerQueueEntries) {\n      if (isQueueWithTtlBackoffInfrastructure(queueEntry)) {\n        addResource(queues, queueEntry.waitQueue.name, queueEntry.waitQueue, \"queue\");\n        addResource(\n          bindings,\n          `${queueEntry.queue.name}WaitBinding`,\n          queueEntry.waitQueueBinding,\n          \"binding\",\n        );\n        addResource(\n          bindings,\n          `${queueEntry.queue.name}RetryBinding`,\n          queueEntry.retryQueueBinding,\n          \"binding\",\n        );\n        addResource(exchanges, queueEntry.waitExchange.name, queueEntry.waitExchange, \"exchange\");\n        addResource(exchanges, queueEntry.retryExchange.name, queueEntry.retryExchange, \"exchange\");\n      }\n    }\n\n    result.consumers = processedConsumers;\n  }\n\n  // Process rpcs section — extract each RPC's queue (and DLX if any) into the\n  // contract topology. RPCs use the AMQP default exchange with the queue name\n  // as routing key, so no exchange or binding declarations are needed.\n  if (inputRpcs && Object.keys(inputRpcs).length > 0) {\n    const processedRpcs: Record<string, RpcDefinition> = {};\n\n    for (const [name, rpc] of Object.entries(inputRpcs)) {\n      processedRpcs[name] = rpc;\n      const queueDef = extractQueue(rpc.queue);\n      addResource(queues, queueDef.name, rpc.queue, \"queue\");\n      if (queueDef.deadLetter?.exchange) {\n        addResource(\n          exchanges,\n          queueDef.deadLetter.exchange.name,\n          queueDef.deadLetter.exchange,\n          \"exchange\",\n        );\n      }\n    }\n\n    result.rpcs = processedRpcs;\n  }\n\n  result.exchanges = exchanges;\n  result.queues = queues;\n  result.bindings = bindings;\n\n  return result as ContractOutput<TContract>;\n}\n","import type { MessageDefinition, QueueEntry, RpcDefinition, RpcErrorMap } from \"../types.js\";\nimport { _internal_assertKnownKeys, _internal_assertStandardSchema } from \"./validate.js\";\n\n/**\n * Define an RPC operation: a request/response pair flowing over a request\n * queue with replies routed back via RabbitMQ direct reply-to.\n *\n * RPC is bidirectional on both ends — the worker handler consumes the request\n * and produces the response; `client.call(name, request, options)` publishes\n * the request and awaits the typed response. Both sides share the same\n * definition, so request and response schemas cannot drift between them.\n *\n * Plug the result into `defineContract({ rpcs: { name: ... } })`. RPCs do not\n * appear in `publishers` or `consumers`.\n *\n * @param queue - The queue that receives RPC requests. The queue name is\n *   used as the routing key on the AMQP default direct exchange.\n * @param messages.request - Schema validated against incoming request payloads\n *   (server side) and outgoing requests (client side).\n * @param messages.response - Schema validated against handler return values\n *   (server side) and incoming replies (client side).\n * @param messages.errors - Optional typed error map: error code → message\n *   definition for the error's `data` payload. Declared errors widen the\n *   handler's `Err` channel (return `Err(rpcError(code, data))`) and the\n *   client's `call()` error union; error data is schema-validated on both\n *   sides. Business errors are replied and acked — never retried.\n *\n * @example\n * ```typescript\n * import { defineQueue, defineMessage, defineRpc, defineContract } from '@amqp-contract/contract';\n * import { z } from 'zod';\n *\n * const getOrder = defineRpc(defineQueue('rpc.get-order'), {\n *   request: defineMessage(z.object({ orderId: z.string() })),\n *   response: defineMessage(z.object({ orderId: z.string(), status: z.string() })),\n *   errors: {\n *     ORDER_NOT_FOUND: defineMessage(z.object({ orderId: z.string() })),\n *   },\n * });\n *\n * const contract = defineContract({ rpcs: { getOrder } });\n *\n * // Server (worker): return the response, or a declared typed error\n * //   handlers: {\n * //     getOrder: ({ payload }) =>\n * //       orders.has(payload.orderId)\n * //         ? OkAsync(orders.get(payload.orderId))\n * //         : ErrAsync(rpcError('ORDER_NOT_FOUND', { orderId: payload.orderId })),\n * //   }\n *\n * // Client: typed call — the error union includes RpcError<'ORDER_NOT_FOUND', { orderId: string }>\n * //   const result = await client.call('getOrder', { orderId: '42' }, { timeoutMs: 5_000 });\n * //   if (result.isErr() && isRpcError(result.error)) console.log(result.error.code);\n * ```\n */\nexport function defineRpc<\n  TRequestMessage extends MessageDefinition,\n  TResponseMessage extends MessageDefinition,\n  TQueue extends QueueEntry,\n  TErrors extends RpcErrorMap | undefined = undefined,\n>(\n  queue: TQueue,\n  messages: { request: TRequestMessage; response: TResponseMessage; errors?: TErrors },\n): RpcDefinition<TRequestMessage, TResponseMessage, TQueue, TErrors> {\n  _internal_assertKnownKeys(\"RPC\", \"(anonymous)\", messages, [\"request\", \"response\", \"errors\"]);\n  _internal_assertStandardSchema(\"RPC request payload schema\", messages.request?.payload);\n  _internal_assertStandardSchema(\"RPC response payload schema\", messages.response?.payload);\n  if (messages.errors !== undefined) {\n    for (const [code, definition] of Object.entries(messages.errors)) {\n      _internal_assertStandardSchema(\n        `RPC error \"${code}\" data schema`,\n        (definition as { payload?: unknown } | undefined)?.payload,\n      );\n    }\n  }\n  return {\n    queue,\n    request: messages.request,\n    response: messages.response,\n    ...(messages.errors !== undefined && { errors: messages.errors }),\n  };\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\n/**\n * Render a single Standard Schema issue as `path.to.field: message` (or just\n * the message for root-level issues). Path segments may be raw property keys\n * or `{ key }` objects per the Standard Schema spec; both are handled.\n *\n * Single source of truth for issue rendering across the client and worker —\n * mirrors temporal-contract's shared formatter (org DNA).\n */\nexport function formatIssue(issue: StandardSchemaV1.Issue): string {\n  const path = (issue.path ?? [])\n    .map((segment) =>\n      typeof segment === \"object\" && segment !== null && \"key\" in segment\n        ? String(segment.key)\n        : String(segment),\n    )\n    .join(\".\");\n  return path.length > 0 ? `${path}: ${issue.message}` : issue.message;\n}\n\n/**\n * Render a list of Standard Schema issues as a single human-readable line:\n * the first `limit` issues joined with `; `, plus a `(+N more)` suffix when\n * truncated. Empty input renders as `\"no issues\"` (defensive — validation\n * failures always carry at least one issue).\n */\nexport function summarizeIssues(issues: readonly StandardSchemaV1.Issue[], limit = 3): string {\n  if (issues.length === 0) {\n    return \"no issues\";\n  }\n  const shown = issues.slice(0, limit).map(formatIssue).join(\"; \");\n  const hidden = issues.length - limit;\n  return hidden > 0 ? `${shown} (+${hidden} more)` : shown;\n}\n"],"mappings":"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"}