/**
* The client is a frozen plain value: create one with `createClient` and
* pass it as the first argument to the functions in the resource modules
* (`domains`, `vps`, `jobs`, ...).
*
* Authentication is a single Bearer credential: either an API key created
* in the account panel (`ird_...`) or an account JWT from the device login
* flow — pass whichever as `apiKey`. A client without `apiKey` can call the
* anonymous endpoints (domain check/example, device login).
*/
import { API_BASE_URL } from './config.js';
import { attachGate } from './gate.js';
export const defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
/** Create an ird API client. Synchronous; makes no requests. */
export const createClient = (options = {}) => Object.freeze({
apiKey: options.apiKey,
apiUrl: (options.apiUrl?.trim() || API_BASE_URL).replace(/\/+$/, ''),
headers: Object.freeze({ ...options.headers }),
timeoutMs: options.timeoutMs,
fetch: options.fetch ?? globalThis.fetch,
sleep: options.sleep ?? defaultSleep,
});
/**
* Create a client with a domain gate: `deniedDomains` are names/patterns
* (`"example.ro"`, `"*.example.ro"`) this client must never mutate, and
* `allowedDomains`, when set, are the ONLY names it may mutate (an empty
* list denies every domain mutation; deny wins over allow).
*
* Requires `apiKey`: the account's registrations are fetched up front to
* map registration ids to domain names, so every domain-touching mutation
* is checked client-side before any request is made. Violations throw a
* `domainDenied` error. See `gate.ts`.
*/
export const createGatedClient = async (options) => attachGate(createClient(options), options);