/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
class Directory {
  constructor(url, cache, options, auth) {
    this.url = url;
    this.#cache = cache;
    this.#auth = auth;
    this.#options = options;
  }
  #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 Error(`HTTP error ${result.statusText} (${result.status}) from ${url}`);
    }
    return result;
  }
}
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);
  }
}
export {
  Directory,
  Repo
};
//# sourceMappingURL=Github.js.map
