export function createCoreDiscoveryClient({ coreUrl, gatewayToken, timeoutMs = 5000, fetchImpl = fetch, } = {}) { const endpoint = normalizeCoreEndpoint(coreUrl); if (typeof gatewayToken !== "string" || gatewayToken.length < 32) { throw new TypeError("device_gateway_core_token_invalid"); } const normalizedTimeout = Number(timeoutMs); if ( !Number.isSafeInteger(normalizedTimeout) || normalizedTimeout < 100 || normalizedTimeout > 30_000 ) { throw new TypeError("device_gateway_core_timeout_invalid"); } if (typeof fetchImpl !== "function") { throw new TypeError("device_gateway_core_fetch_invalid"); } return async function observeDiscovery(signal) { const response = await fetchImpl(endpoint, { method: "POST", headers: { Authorization: `Bearer ${gatewayToken}`, "Content-Type": "application/json", }, body: JSON.stringify(signal), signal: AbortSignal.timeout(normalizedTimeout), }); const body = await readBoundedJson(response, 32 * 1024); if (!response.ok || body?.ok !== true) { throw new Error("device_gateway_core_ingest_failed"); } if ( !body.discovery || body.discovery.lifecycleState !== "quarantine" || body.discovery.commandTransport !== "disabled" ) { throw new Error("device_gateway_core_ingest_contract_invalid"); } return body.discovery; }; } function normalizeCoreEndpoint(value) { let url; try { url = new URL(String(value || "")); } catch { throw new TypeError("device_gateway_core_url_invalid"); } if (url.protocol !== "http:" || url.username || url.password) { throw new TypeError("device_gateway_core_url_invalid"); } if (url.pathname !== "/" || url.search || url.hash) { throw new TypeError("device_gateway_core_url_invalid"); } url.pathname = "/internal/v1/device-discoveries:observe"; return url.toString(); } async function readBoundedJson(response, maxBytes) { const text = await response.text(); if (Buffer.byteLength(text, "utf8") > maxBytes) { throw new Error("device_gateway_core_response_too_large"); } try { return JSON.parse(text); } catch { throw new Error("device_gateway_core_response_invalid"); } }