{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../src/registry/fetcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,KAAK,QAAQ,EAAoB,MAAM,aAAa,CAAC;AAE9D,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,CAAC;AAU7C,MAAM,MAAM,mBAAmB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnH;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CAC1C,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,YAAuB,EAChC,SAAS,GAAE,OAAO,KAAwB,GACxC,OAAO,CAAC,mBAAmB,CAAC,CA+C9B","sourcesContent":["/**\n * WS15: Registry fetcher — HTTP fetch + atomic cache write.\n *\n * Fetches the registry from the remote URL, validates it, and writes to\n * ~/.cave/agent/registry-cache.json atomically (write-then-rename).\n */\n\nimport { mkdirSync, renameSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { type Registry, validateRegistry } from \"./schema.js\";\n\nexport type FetchChannel = \"stable\" | \"beta\";\n\nconst REGISTRY_URLS: Record<FetchChannel, string> = {\n\tstable: \"https://raw.githubusercontent.com/Zhachory1/mewritecode/main/registry/registry.json\",\n\tbeta: \"https://raw.githubusercontent.com/Zhachory1/mewritecode/main/registry/registry.json\",\n};\n\n/** Default timeout for registry fetch (ms) */\nconst FETCH_TIMEOUT_MS = 10_000;\n\nexport type FetchRegistryResult = { ok: true; registry: Registry; cached: boolean } | { ok: false; error: string };\n\n/**\n * Fetch registry JSON from remote URL, validate, and atomically write to\n * cachePath. Returns the validated Registry on success.\n *\n * @param cachePath  Absolute path to write the cache file.\n * @param channel    \"stable\" (default) or \"beta\".\n * @param fetchImpl  Injectable fetch (defaults to globalThis.fetch / Node 18+).\n */\nexport async function fetchAndCacheRegistry(\n\tcachePath: string,\n\tchannel: FetchChannel = \"stable\",\n\tfetchImpl: typeof fetch = globalThis.fetch,\n): Promise<FetchRegistryResult> {\n\tconst url = REGISTRY_URLS[channel];\n\n\tlet raw: unknown;\n\ttry {\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n\t\tconst response = await fetchImpl(url, { signal: controller.signal });\n\t\tclearTimeout(timer);\n\n\t\tif (!response.ok) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `HTTP ${response.status} fetching registry from ${url}`,\n\t\t\t};\n\t\t}\n\n\t\traw = await response.json();\n\t} catch (err) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Failed to fetch registry: ${err instanceof Error ? err.message : String(err)}`,\n\t\t};\n\t}\n\n\tconst result = validateRegistry(raw);\n\tif (!result.ok) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Registry validation failed:\\n${result.errors.join(\"\\n\")}`,\n\t\t};\n\t}\n\n\t// Atomic write: write to tmp then rename\n\ttry {\n\t\tmkdirSync(dirname(cachePath), { recursive: true });\n\t\tconst tmpPath = join(tmpdir(), `cave-registry-${Date.now()}.json`);\n\t\twriteFileSync(tmpPath, JSON.stringify(result.registry, null, 2), \"utf-8\");\n\t\trenameSync(tmpPath, cachePath);\n\t} catch (err) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Failed to write registry cache: ${err instanceof Error ? err.message : String(err)}`,\n\t\t};\n\t}\n\n\treturn { ok: true, registry: result.registry, cached: true };\n}\n"]}