import { PackageId, ServiceInterfaceId, ServiceInterfaceType } from '../types'; import { AddressInfo, Host, Hostname, HostnameInfo } from '../types'; import { Effects } from '../Effects'; import { Watchable } from './Watchable'; export type UrlString = string; export type HostId = string; export declare const getHostname: (url: string) => Hostname | null; /** * The kinds of hostnames that can be filtered on. * * - `'mdns'` — mDNS / Bonjour `.local` hostnames * - `'domain'` — any os-managed domain name (matches both `'private-domain'` and `'public-domain'` metadata kinds) * - `'ip'` — shorthand for both `'ipv4'` and `'ipv6'` * - `'ipv4'` — IPv4 addresses only * - `'ipv6'` — IPv6 addresses only * - `'localhost'` — loopback addresses (`localhost`, `127.0.0.1`, `::1`) * - `'link-local'` — IPv6 link-local addresses (fe80::/10) * - `'bridge'` — The LXC bridge interface * - `'plugin'` — hostnames provided by a plugin package */ type FilterKinds = 'mdns' | 'domain' | 'ip' | 'ipv4' | 'ipv6' | 'localhost' | 'link-local' | 'bridge' | 'plugin'; /** * Describes which hostnames to include (or exclude) when filtering a `Filled` address. * * Every field is optional — omitted fields impose no constraint. * Filters are composable: the `.filter()` method intersects successive filters, * and the `exclude` field inverts a nested filter. */ export type Filter = { /** Keep only hostnames with the given visibility. `'public'` = externally reachable, `'private'` = LAN-only. */ visibility?: 'public' | 'private'; /** Keep only hostnames whose metadata kind matches. A single kind or array of kinds. `'ip'` expands to `['ipv4','ipv6']`, `'domain'` matches both `'private-domain'` and `'public-domain'`. */ kind?: FilterKinds | FilterKinds[]; /** Arbitrary predicate — hostnames for which this returns `false` are excluded. */ predicate?: (h: HostnameInfo) => boolean; /** Keep only plugin hostnames provided by this package. Implies `kind: 'plugin'`. */ pluginId?: PackageId; /** A nested filter whose matches are *removed* from the result (logical NOT). */ exclude?: Filter; }; type VisibilityFilter = V extends 'public' ? (HostnameInfo & { public: true; }) | VisibilityFilter> : V extends 'private' ? (HostnameInfo & { public: false; }) | VisibilityFilter> : never; type KindFilter = K extends 'mdns' ? (HostnameInfo & { metadata: { kind: 'mdns'; }; }) | KindFilter> : K extends 'domain' ? (HostnameInfo & { metadata: { kind: 'private-domain'; }; }) | (HostnameInfo & { metadata: { kind: 'public-domain'; }; }) | KindFilter> : K extends 'ipv4' ? (HostnameInfo & { metadata: { kind: 'ipv4'; }; }) | KindFilter> : K extends 'ipv6' ? (HostnameInfo & { metadata: { kind: 'ipv6'; }; }) | KindFilter> : K extends 'plugin' ? (HostnameInfo & { metadata: { kind: 'plugin'; }; }) | KindFilter> : K extends 'ip' ? KindFilter | 'ipv4' | 'ipv6'> : never; type FilterReturnTy = F extends { visibility: infer V extends 'public' | 'private'; } ? VisibilityFilter & FilterReturnTy> : F extends { kind: (infer K extends FilterKinds) | (infer K extends FilterKinds)[]; } ? KindFilter & FilterReturnTy> : F extends { predicate: (h: HostnameInfo) => h is infer H extends HostnameInfo; } ? H & FilterReturnTy> : F extends { exclude: infer E extends Filter; } ? HostnameInfo extends FilterReturnTy ? HostnameInfo : Exclude> : HostnameInfo; declare const nonLocalFilter: { readonly exclude: { readonly kind: ("localhost" | "link-local" | "bridge")[]; }; }; declare const publicFilter: { readonly visibility: "public"; }; type Formats = 'hostname-info' | 'urlstring' | 'url'; type FormatReturnTy = Format extends 'hostname-info' ? FilterReturnTy | FormatReturnTy> : Format extends 'url' ? URL | FormatReturnTy> : Format extends 'urlstring' ? UrlString | FormatReturnTy> : never; /** * A resolved address with its hostnames already populated, plus helpers * for filtering, formatting, and converting hostnames to URLs. * * Filters are chainable and each call returns a new `Filled` narrowed to the * matching subset of hostnames: * * ```ts * addresses.nonLocal // exclude localhost & link-local * addresses.public // only publicly-reachable hostnames * addresses.filter({ kind: 'domain' }) // only domain-name hostnames * addresses.filter({ visibility: 'private' }) // only LAN-reachable hostnames * addresses.nonLocal.filter({ kind: 'ip' }) // chainable — non-local IPs only * ``` */ export type Filled = { /** The hostnames that survived all applied filters. */ hostnames: HostnameInfo[]; /** Convert a single hostname into a fully-formed URL string, applying the address's scheme, username, and suffix. */ toUrl: (h: HostnameInfo) => UrlString; /** * Return every hostname in the requested format. * * - `'urlstring'` (default) — formatted URL strings * - `'url'` — `URL` objects * - `'hostname-info'` — raw `HostnameInfo` objects */ format: (format?: Format) => FormatReturnTy<{}, Format>[]; /** * Apply an arbitrary {@link Filter} and return a new `Filled` containing only * the hostnames that match. Filters compose: calling `.filter()` on an * already-filtered `Filled` intersects the constraints. */ filter: (filter: NewFilter) => Filled; /** * Apply multiple filters and return hostnames that match **any** of them (union / OR). * * ```ts * addresses.matchesAny([{ kind: 'domain' }, { kind: 'mdns' }]) * ``` */ matchesAny: (filters: [...NewFilters]) => Filled; /** Shorthand filter that excludes `localhost` and IPv6 link-local addresses — keeps only network-reachable hostnames. */ nonLocal: Filled; /** Shorthand filter that keeps only publicly-reachable hostnames (those with `public: true`). */ public: Filled; }; export type FilledAddressInfo = AddressInfo & Filled; export type ServiceInterfaceFilled = { id: string; /** The title of this field to be displayed */ name: string; /** Human readable description, used as tooltip usually */ description: string; /** Whether or not to mask the URIs for this interface. Useful if the URIs contain sensitive information, such as a password, macaroon, or API key */ masked: boolean; /** Information about the host for this binding */ host: Host | null; /** URI information */ addressInfo: FilledAddressInfo | null; /** Indicates if we are a ui/p2p/api for the kind of interface that this is representing */ type: ServiceInterfaceType; }; export declare const addressHostToUrl: ({ scheme, sslScheme, username, suffix }: AddressInfo, hostname: HostnameInfo) => UrlString; /** * Filters out localhost and IPv6 link-local hostnames from a list. * Equivalent to the `nonLocal` filter on `Filled` addresses. */ export declare function filterNonLocal(hostnames: HostnameInfo[]): HostnameInfo[]; export declare const filledAddress: (host: Host, addressInfo: AddressInfo) => FilledAddressInfo; export declare class GetServiceInterface extends Watchable { readonly opts: { id: string; packageId?: string; }; protected readonly label = "GetServiceInterface"; constructor(effects: Effects, opts: { id: string; packageId?: string; }, options?: { map?: (value: ServiceInterfaceFilled | null) => Mapped; eq?: (a: Mapped, b: Mapped) => boolean; }); protected fetch(callback?: () => void): Promise; } export declare function getOwnServiceInterface(effects: Effects, id: ServiceInterfaceId): GetServiceInterface; export declare function getOwnServiceInterface(effects: Effects, id: ServiceInterfaceId, map: (interfaces: ServiceInterfaceFilled | null) => Mapped, eq?: (a: Mapped, b: Mapped) => boolean): GetServiceInterface; export declare function getServiceInterface(effects: Effects, opts: { id: ServiceInterfaceId; packageId: PackageId; }): GetServiceInterface; export declare function getServiceInterface(effects: Effects, opts: { id: ServiceInterfaceId; packageId: PackageId; }, map: (interfaces: ServiceInterfaceFilled | null) => Mapped, eq?: (a: Mapped, b: Mapped) => boolean): GetServiceInterface; export {};