| 1 | import { environmentEndpointUrl } from "./environment/endpoint.ts"; |
| 2 | import type { ScheduledTaskWebhookEndpoint } from "@t3tools/contracts"; |
| 3 | import { isLocalLoopbackHost } from "@t3tools/shared/hostClassification"; |
| 4 | |
| 5 | /** |
| 6 | * Where a sender can call a webhook task, as a client shows it. With T3 |
| 7 | * Connect the server returns a public URL; without it the path is resolved on |
| 8 | * the address this client reaches the environment at. |
| 9 | */ |
| 10 | export interface WebhookAddress { |
| 11 | /** The URL to give a sender, or the bare path when no address is known. */ |
| 12 | readonly address: string; |
| 13 | /** Whether `address` is a full URL a sender can call. */ |
| 14 | readonly copyable: boolean; |
| 15 | /** One line on who can reach `address`; null for a T3 Connect URL. */ |
| 16 | readonly note: string | null; |
| 17 | } |
| 18 | |
| 19 | export function webhookAddress( |
| 20 | endpoint: ScheduledTaskWebhookEndpoint, |
| 21 | httpBaseUrl: string | null, |
| 22 | ): WebhookAddress { |
| 23 | if (endpoint.url !== null) { |
| 24 | return { address: endpoint.url, copyable: true, note: null }; |
| 25 | } |
| 26 | if (httpBaseUrl === null) { |
| 27 | return { |
| 28 | address: endpoint.path, |
| 29 | copyable: false, |
| 30 | note: "Link this environment to T3 Connect for a public URL.", |
| 31 | }; |
| 32 | } |
| 33 | const url = new URL(environmentEndpointUrl(httpBaseUrl, endpoint.path)); |
| 34 | return { |
| 35 | address: url.href, |
| 36 | copyable: true, |
| 37 | note: isLocalLoopbackHost(url.hostname) |
| 38 | ? "Only this computer can call this address. Link T3 Connect for a public URL." |
| 39 | : "Works wherever this environment's address is reachable, for example over Tailscale or your own proxy. Link T3 Connect for a public URL.", |
| 40 | }; |
| 41 | } |