import type { IDnsProviderClient } from './interfaces.js'; import type { TDnsProviderType, TDnsProviderCredentials, } from '../../../ts_interfaces/data/dns-provider.js'; import { CloudflareDnsProvider } from './cloudflare.provider.js'; /** * Instantiate a runtime DNS provider client from a stored DnsProviderDoc. * * @throws if the provider type is not supported. * * ## Adding a new provider (e.g. Route53) * * 1. **Type union** — extend `TDnsProviderType` in * `ts_interfaces/data/dns-provider.ts` (e.g. `'cloudflare' | 'route53'`). * 2. **Credentials interface** — add `IRoute53Credentials` and append it to * the `TDnsProviderCredentials` discriminated union. * 3. **Descriptor** — append a new entry to `dnsProviderTypeDescriptors` so * the OpsServer UI picks up the new type and renders the right credential * form fields automatically. * 4. **Provider class** — create `ts/dns/providers/route53.provider.ts` * implementing `IDnsProviderClient`. * 5. **Factory case** — add a new `case 'route53':` below. The * `_exhaustive: never` line will fail to compile until you do. * 6. **Index** — re-export the new class from `ts/dns/providers/index.ts`. */ export function createDnsProvider( type: TDnsProviderType, credentials: TDnsProviderCredentials, ): IDnsProviderClient { switch (type) { case 'cloudflare': { if (credentials.type !== 'cloudflare') { throw new Error( `createDnsProvider: type mismatch — provider type is 'cloudflare' but credentials.type is '${credentials.type}'`, ); } return new CloudflareDnsProvider(credentials.apiToken); } case 'dcrouter': { // The built-in DcRouter pseudo-provider has no runtime client — dcrouter // itself serves the records via the embedded smartdns.DnsServer. This // case exists only to satisfy the exhaustive switch; it should never // actually run because the handler layer rejects any CRUD that would // result in a DnsProviderDoc with type: 'dcrouter'. throw new Error( `createDnsProvider: 'dcrouter' is a built-in pseudo-provider — no runtime client exists. ` + `This call indicates a DnsProviderDoc with type: 'dcrouter' was persisted, which should never happen.`, ); } default: { // If you see a TypeScript error here after extending TDnsProviderType, // add a `case` for the new type above. The `never` enforces exhaustiveness. const _exhaustive: never = type; throw new Error(`createDnsProvider: unsupported provider type: ${_exhaustive}`); } } }