/** * The managed channel protocol. * * A channel is one inbound messaging surface with one external platform. It may * contribute Events ingress, outbound messaging, and deploy requirements. * Discovery is file-based: the CLI globs modules under `channels/` that export a * `channel`, imports each one, and hands them to {@link collectChannels}, which * stamps each with its file-stem `name`. */ import type { ChannelManifest } from "../channels/manifest.js"; import type { ChannelTransport } from "../channels/runtime.js"; /** * Realm-global brand marking a value as a managed channel. `Symbol.for` keeps * the identity stable across duplicate module instances. */ export declare const CHANNEL_BRAND: unique symbol; /** * Context handed to {@link Channel.events} for its public inbound route. */ export interface ChannelEventsContext { /** File-stem channel name (route segment). */ readonly name: string; /** The inbound request. */ readonly request: Request; /** * Pre-read raw body when the HTTP framework may have consumed `request` * (Hono mount passes `await c.req.text()`). */ readonly rawBody?: string | Uint8Array; /** The live channel instance. */ readonly channel: Channel; } /** Deploy/runtime requirements a channel declares. */ export type ChannelRequirements = ChannelManifest; /** * A managed channel. Implement at least one of {@link Channel.events}, * {@link Channel.messaging}, or {@link Channel.requirements}; a channel * implementing none does nothing and is rejected by {@link collectChannels}. */ export interface Channel { readonly [CHANNEL_BRAND]: true; /** * Diagnostic / provider label (e.g. `"slack"`). * HTTP mounts use {@link name}, not kind. */ readonly kind: string; /** Optional provider-neutral ingress transport discriminator. */ readonly transport?: "trigger_server"; /** * File-stem instance name, stamped by {@link collectChannels}. Mount * namespace and messaging address (`runtime.channel` / `deliverTo`). */ readonly name?: string; /** * Handle the channel's public Events route. Trigger-backed channels mount at * `/v1/channels/{name}/events`; ordinary channels use `/channels/{name}/events`. */ events?(ctx: ChannelEventsContext): Response | Promise; /** Build outbound messaging transport for `runtime.channel` / schedule delivery. */ messaging?(env: NodeJS.ProcessEnv): ChannelTransport | undefined; /** Deploy/runtime requirements (env, permissions, connection, provider config). */ requirements?(name: string): ChannelRequirements; } /** True when any channel can start an ingress run via {@link Channel.events}. */ export declare function hasIngressChannels(channels: readonly Channel[] | undefined): boolean; /** * Build the requirements map (file-stem → manifest) from channels that * implement {@link Channel.requirements}. */ export declare function requirementsFromChannels(channels: readonly Channel[]): Record; /** A discovered `channels/` module paired with its source path for diagnostics. */ export interface DiscoveredChannelModule { /** Project-relative path of the module, used in error messages. */ readonly source: string; /** The imported module namespace; its `channel` export is the channel. */ readonly module: { channel?: unknown; } & Record; } /** Narrow an arbitrary value to a {@link Channel} by its brand. */ export declare function isChannel(value: unknown): value is Channel; /** * Validate and collect the channels discovered under `channels/`. * * Each module should expose exactly one channel as `export const channel`. * The file stem becomes the instance {@link Channel.name} (mount namespace and * messaging address). Duplicate stems are a hard error. Modules with no such * export, or whose `channel` is not branded, are skipped. A branded channel * that implements no hooks is still a hard error. */ export declare function collectChannels(modules: readonly DiscoveredChannelModule[]): Channel[]; //# sourceMappingURL=channel.d.ts.map