/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { MatterError } from "../MatterError.js";
var Github;
((Github2) => {
  class HttpError extends MatterError {
    constructor(message, statusCode) {
      super(message);
      this.statusCode = statusCode;
    }
    statusCode;
    /** True for the statuses GitHub uses to signal rate limiting. */
    get isRateLimit() {
      return this.statusCode === 403 || this.statusCode === 429;
    }
  }
  Github2.HttpError = HttpError;
  class Directory {
    constructor(url, cache, options, auth) {
      this.url = url;
      this.#cache = cache;
      this.#auth = auth;
      this.#options = options;
    }
    url;
    #cache;
    #auth;
    #options;
    #contents = {};
    async ls() {
      await this.load();
      return Object.keys(this.#contents);
    }
    async cd(name) {
      const path = name.split("/");
      let result = this;
      for (const p of path) {
        const entry = await result.find(p);
        if (entry.type !== "tree") throw new Error(`Path "${p}" not a directory`);
        result = new Directory(entry.url, this.#cache, this.#options, this.#auth);
      }
      return result;
    }
    async get(name) {
      const entry = await this.find(name);
      if (entry.type !== "blob") throw new Error(`Path "${name}" not a regular file`);
      return await this.fetch(entry.url);
    }
    async getBinary(name) {
      const entry = await this.find(name);
      if (entry.type !== "blob") throw new Error(`Path "${name}" not a regular file`);
      return await this.fetchBinary(entry.url);
    }
    async load() {
      if (Object.keys(this.#contents).length) return;
      const tree = (await JSON.parse(await this.fetch(this.url))).tree;
      if (!tree) throw new Error("No tree in fetch response");
      tree.forEach((e) => this.#contents[e.path] = e);
    }
    async find(name) {
      await this.load();
      const entry = this.#contents[name];
      if (!entry) throw new Error(`Path "${name}" not found`);
      return entry;
    }
    async fetch(url) {
      return this.#cache(url.replace(/^https:\/\//, ""), async () => {
        const result = await this.doFetch(url);
        return await result.text();
      });
    }
    async fetchBinary(url) {
      const result = await this.doFetch(url);
      const arrayBuffer = await result.arrayBuffer();
      return new Uint8Array(arrayBuffer);
    }
    /**
     * Perform the actual fetch request with common options
     */
    async doFetch(url) {
      const fetchOptions = {
        headers: {
          accept: "application/vnd.github.raw"
        }
      };
      if (this.#auth) {
        fetchOptions.headers.Authorization = `Bearer ${this.#auth.trim()}`;
      }
      if (this.#options?.timeout) {
        fetchOptions.signal = AbortSignal.timeout(this.#options.timeout);
      }
      const result = await fetch(url, fetchOptions);
      if (result.status !== 200) {
        throw new HttpError(`HTTP error ${result.statusText} (${result.status}) from ${url}`, result.status);
      }
      return result;
    }
  }
  Github2.Directory = Directory;
  class Repo extends Directory {
    constructor(org, repo, branch, options, cache = (name, generator) => generator(name), auth) {
      super(`https://api.github.com/repos/${org}/${repo}/git/trees/${branch}`, cache, options, auth);
    }
  }
  Github2.Repo = Repo;
})(Github || (Github = {}));
export {
  Github
};
//# sourceMappingURL=Github.js.map
