{"version":3,"file":"fastkv.cjs","names":[],"sources":["../src/fastkv.ts"],"sourcesContent":["export type NetworkId = \"mainnet\" | \"testnet\";\n\ninterface FastKvEntry {\n  value: unknown;\n}\n\ninterface FastKvListResponse {\n  entries?: Array<FastKvEntry | null>;\n}\n\nconst FASTKV_TIMEOUT_MS = 10_000;\n\nfunction getNetworkIdForAccount(accountId: string): NetworkId {\n  return accountId.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n\nexport function getFastKvBaseUrlForNetwork(network: NetworkId): string {\n  return network === \"testnet\"\n    ? process.env.REGISTRY_FASTKV_TESTNET_URL || \"https://kv.test.fastnear.com\"\n    : process.env.REGISTRY_FASTKV_MAINNET_URL || \"https://kv.main.fastnear.com\";\n}\n\nfunction getFastKvBaseUrlForAccount(accountId: string): string {\n  return getNetworkIdForAccount(accountId) === \"testnet\"\n    ? getFastKvBaseUrlForNetwork(\"testnet\")\n    : getFastKvBaseUrlForNetwork(\"mainnet\");\n}\n\nexport function buildRegistryConfigUrl(accountId: string, gatewayId: string): string {\n  const baseUrl = getFastKvBaseUrlForAccount(accountId);\n  const namespace = getRegistryNamespaceForAccount(accountId);\n  const key = encodeURIComponent(getRegistryConfigKey(accountId, gatewayId));\n  return `${baseUrl}/v0/latest/${encodeURIComponent(namespace)}/${encodeURIComponent(accountId)}/${key}`;\n}\n\nexport function buildRegistryConfigUrlForNetwork(\n  network: NetworkId,\n  accountId: string,\n  gatewayId: string,\n): string {\n  const baseUrl = getFastKvBaseUrlForNetwork(network);\n  const namespace = getRegistryNamespaceForNetwork(network);\n  const key = encodeURIComponent(getRegistryConfigKey(accountId, gatewayId));\n  return `${baseUrl}/v0/latest/${encodeURIComponent(namespace)}/${encodeURIComponent(accountId)}/${key}`;\n}\n\nexport function getRegistryNamespaceForAccount(accountId: string): string {\n  return accountId.endsWith(\".testnet\")\n    ? process.env.REGISTRY_FASTKV_TESTNET_NAMESPACE || \"dev.everything.near\"\n    : process.env.REGISTRY_FASTKV_MAINNET_NAMESPACE || \"dev.everything.near\";\n}\n\nexport function getRegistryNamespaceForNetwork(network: NetworkId): string {\n  return network === \"testnet\"\n    ? process.env.REGISTRY_FASTKV_TESTNET_NAMESPACE || \"dev.everything.near\"\n    : process.env.REGISTRY_FASTKV_MAINNET_NAMESPACE || \"dev.everything.near\";\n}\n\nfunction getRegistryConfigKey(\n  accountId: string,\n  gatewayId: string,\n  pathSegments: string[] = [],\n): string {\n  const suffix =\n    pathSegments.length > 0\n      ? `/${pathSegments.map((segment) => encodeURIComponent(segment)).join(\"/\")}`\n      : \"\";\n  return `apps/${accountId}/${gatewayId}${suffix}/bos.config.json`;\n}\n\nfunction parseBosUrl(bosUrl: string): {\n  accountId: string;\n  gatewayId: string;\n  pathSegments: string[];\n} {\n  const match = bosUrl.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n  if (!match?.[1] || !match[2]) {\n    throw new Error(`Invalid BOS URL: ${bosUrl}`);\n  }\n\n  const pathSegments = match[2]\n    .split(\"/\")\n    .filter(Boolean)\n    .map((segment) => decodeURIComponent(segment));\n  if (pathSegments.length === 0) {\n    throw new Error(`Invalid BOS URL: ${bosUrl}`);\n  }\n\n  const [gatewayId, ...pathSegmentsTail] = pathSegments;\n  if (!gatewayId) {\n    throw new Error(`Invalid BOS URL: ${bosUrl}`);\n  }\n\n  return {\n    accountId: match[1],\n    gatewayId,\n    pathSegments: pathSegmentsTail,\n  };\n}\n\nexport async function fetchBosConfigFromFastKv<T>(bosUrl: string): Promise<T> {\n  const { accountId, gatewayId, pathSegments } = parseBosUrl(bosUrl);\n  const payload = await fetchJson<FastKvListResponse>(\n    `${getFastKvBaseUrlForAccount(accountId)}/v0/latest/${encodeURIComponent(getRegistryNamespaceForAccount(accountId))}/${encodeURIComponent(accountId)}`,\n    {\n      method: \"POST\",\n      body: JSON.stringify({\n        key: getRegistryConfigKey(accountId, gatewayId, pathSegments),\n        limit: 1,\n      }),\n    },\n  );\n  const value = payload?.entries?.find(Boolean)?.value;\n\n  if (!value) {\n    throw new Error(`No config found for ${bosUrl}`);\n  }\n\n  if (typeof value === \"string\") {\n    return JSON.parse(value) as T;\n  }\n\n  if (typeof value !== \"object\") {\n    throw new Error(`Invalid config value for ${bosUrl}`);\n  }\n\n  return value as T;\n}\n\nexport interface PluginManifest {\n  schemaVersion: number;\n  kind: string;\n  plugin: { name: string; version: string };\n  runtime: { remoteEntry: string };\n  contract: {\n    kind: string;\n    types: { path: string; exportName: string; typeName: string; sha256: string };\n  };\n  additionalExports?: Array<{ path: string; exports: string[]; sha256: string }>;\n}\n\nexport async function fetchRemotePluginManifest(cdnUrl: string): Promise<PluginManifest | null> {\n  try {\n    const controller = new AbortController();\n    const timeout = setTimeout(() => controller.abort(), FASTKV_TIMEOUT_MS);\n    const baseUrl = cdnUrl.replace(/\\/$/, \"\");\n    const response = await fetch(`${baseUrl}/plugin.manifest.json`, {\n      signal: controller.signal,\n    });\n    clearTimeout(timeout);\n    if (!response.ok) return null;\n    return (await response.json()) as PluginManifest;\n  } catch {\n    return null;\n  }\n}\n\nasync function fetchJson<T>(url: string, init?: RequestInit): Promise<T | null> {\n  const controller = new AbortController();\n  const timeout = setTimeout(() => controller.abort(), FASTKV_TIMEOUT_MS);\n\n  try {\n    const response = await fetch(url, {\n      ...init,\n      headers: {\n        accept: \"application/json\",\n        \"content-type\": \"application/json\",\n        ...(init?.headers ?? {}),\n      },\n      signal: controller.signal,\n    });\n\n    if (!response.ok) {\n      return null;\n    }\n\n    return (await response.json()) as T;\n  } finally {\n    clearTimeout(timeout);\n  }\n}\n"],"mappings":"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"}