(ns ird.client
"Clojure client for the ird public API (https://api.ird.ro).
Create a client with `make-client`, then call functions in the resource
namespaces (`ird.domains`, `ird.vps`, `ird.jobs`, …). Request bodies and
responses use plain maps whose keys match the documented snake_case field
names (e.g. {:auto_renew true}).
Authentication is a single Bearer credential: either an API key created in
the account panel (`ird_...`) or an account JWT from the `ird login` device
flow — pass whichever as :api-key. A client without :api-key can call the
anonymous endpoints (domain check/example, device login)."
(:require
[clojure.string :as str]
[ird.config :as config]))
(defn make-client
"Create an ird API client.
Options:
:api-key (optional) API key (`ird_...`) or account JWT, sent as
a Bearer token. Omit for anonymous access to the few
endpoints that allow it.
:api-url (optional) base URL override; defaults to
https://api.ird.ro.
:http-opts (optional) map merged into every request map passed to
babashka.http-client (e.g. {:timeout 30000}).
:verbose (optional) when truthy, prints method and URL for each
request.
:denied-domains (optional) domain names/patterns (e.g. \"example.ro\",
\"*.example.ro\") that this client must never mutate,
even though the account could.
:allowed-domains (optional) when set, ONLY these domain names/patterns
may be mutated; everything else is denied (an empty
collection denies every domain mutation). Deny wins
over allow when both are set.
When either domain-gate option is set, the client eagerly fetches the
account's registrations to map registration ids to domain names (requires
:api-key) and every domain-touching mutation is checked client-side before
any request is made; violations throw an :ird/domain-denied ex-info. See
ird.gate."
[{:keys [api-key api-url http-opts verbose denied-domains allowed-domains]}]
(let [client {:api-key api-key
:api-url (or (not-empty api-url) config/api-base-url)
:http-opts http-opts
:verbose verbose}]
(if (or denied-domains allowed-domains)
((requiring-resolve 'ird.gate/attach)
client
{:denied-domains denied-domains
:allowed-domains allowed-domains})
client)))