{"version":3,"file":"github.cjs","names":["binaryExtensions","name: string","extname","BaseDocumentLoader","githubUrl: string","UnknownHandling","AsyncCaller","url: string","documents: Document[]","Document","gitmodulesContent: string","submoduleInfo: SubmoduleInfo","path: string","fileType: string","file: GithubFile","files: GithubFile[]","currentDirectoryFilePromises: Promise<GetContentResponse>[]","currentDirectoryDirectoryPromises: Promise<\n      Promise<GetContentResponse>[]\n    >[]","curDirDirectories: Promise<GetContentResponse>[][]","message: string"],"sources":["../../../src/document_loaders/web/github.ts"],"sourcesContent":["import ignore, { Ignore } from \"ignore\";\nimport binaryExtensions from \"binary-extensions\";\n\nimport { Document } from \"@langchain/core/documents\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport {\n  AsyncCaller,\n  AsyncCallerParams,\n} from \"@langchain/core/utils/async_caller\";\nimport { BaseDocumentLoader } from \"@langchain/core/document_loaders/base\";\nimport { UnknownHandling } from \"@langchain/classic/document_loaders/fs/directory\";\nimport { extname } from \"../../utils/extname.js\";\n\nconst extensions = /* #__PURE__ */ new Set(binaryExtensions);\n\n/**\n * A function that checks if a file path is a binary file based on its\n * extension.\n * @param name The file path to check.\n * @returns A boolean indicating whether the file path is a binary file.\n */\nfunction isBinaryPath(name: string) {\n  return extensions.has(extname(name).slice(1).toLowerCase());\n}\n\n/**\n * An interface that represents a file in a GitHub repository. It has\n * properties for the file name, path, SHA, size, URLs, type, and links.\n */\nexport interface GithubFile {\n  name: string;\n  path: string;\n  sha: string;\n  size: number;\n  url: string;\n  html_url: string;\n  git_url: string;\n  download_url: string;\n  type: string;\n  _links: {\n    self: string;\n    git: string;\n    html: string;\n  };\n}\n\n/**\n * An interface that represents the response from fetching the content of\n * a file. It has properties for the file contents and metadata.\n */\ninterface GetContentResponse {\n  contents: string;\n  metadata: { source: string; repository: string; branch: string };\n}\n\n/**\n * An interface describing the submodules of a Git repository.\n */\ninterface SubmoduleInfo {\n  name: string;\n  path: string;\n  url: string;\n  ref: string;\n}\n\n/**\n * An interface that represents the parameters for the GithubRepoLoader\n * class. It extends the AsyncCallerParams interface and adds additional\n * properties specific to the GitHub repository loader.\n */\nexport interface GithubRepoLoaderParams extends AsyncCallerParams {\n  /**\n   * The base URL of the GitHub instance.\n   * To be used when you are not targeting github.com, e.g. a GitHub Enterprise instance.\n   */\n  baseUrl?: string;\n  /**\n   * The API endpoint URL of the GitHub instance.\n   * To be used when you are not targeting github.com, e.g. a GitHub Enterprise instance.\n   */\n  apiUrl?: string;\n  branch?: string;\n  recursive?: boolean;\n  /**\n   * Set to true to recursively process submodules. Is only effective, when recursive=true.\n   */\n  processSubmodules?: boolean;\n  unknown?: UnknownHandling;\n  accessToken?: string;\n  ignoreFiles?: (string | RegExp)[];\n  ignorePaths?: string[];\n  verbose?: boolean;\n  /**\n   * The maximum number of concurrent calls that can be made. Defaults to 2.\n   */\n  maxConcurrency?: number;\n  /**\n   * The maximum number of retries that can be made for a single call,\n   * with an exponential backoff between each attempt. Defaults to 2.\n   */\n  maxRetries?: number;\n}\n\n/**\n * A class that extends the BaseDocumentLoader and implements the\n * GithubRepoLoaderParams interface. It represents a document loader for\n * loading files from a GitHub repository.\n */\nexport class GithubRepoLoader\n  extends BaseDocumentLoader\n  implements GithubRepoLoaderParams\n{\n  public baseUrl: string;\n\n  public apiUrl: string;\n\n  private readonly owner: string;\n\n  private readonly repo: string;\n\n  private readonly initialPath: string;\n\n  private headers: Record<string, string> = {};\n\n  public branch: string;\n\n  public recursive: boolean;\n\n  public processSubmodules: boolean;\n\n  public unknown: UnknownHandling;\n\n  public accessToken?: string;\n\n  public ignoreFiles: (string | RegExp)[];\n\n  public ignore?: Ignore;\n\n  public verbose?: boolean;\n\n  public maxConcurrency?: number;\n\n  public maxRetries?: number;\n\n  protected caller: AsyncCaller;\n\n  public ignorePaths?: string[];\n\n  private submoduleInfos: SubmoduleInfo[];\n\n  constructor(\n    githubUrl: string,\n    {\n      accessToken = getEnvironmentVariable(\"GITHUB_ACCESS_TOKEN\"),\n      baseUrl = \"https://github.com\",\n      apiUrl = \"https://api.github.com\",\n      branch = \"main\",\n      recursive = true,\n      processSubmodules = false,\n      unknown = UnknownHandling.Warn,\n      ignoreFiles = [],\n      ignorePaths,\n      verbose = false,\n      maxConcurrency = 2,\n      maxRetries = 2,\n      ...rest\n    }: GithubRepoLoaderParams = {}\n  ) {\n    super();\n    this.baseUrl = baseUrl;\n    this.apiUrl = apiUrl;\n    const { owner, repo, path } = this.extractOwnerAndRepoAndPath(githubUrl);\n    this.owner = owner;\n    this.repo = repo;\n    this.initialPath = path;\n    this.branch = branch;\n    this.recursive = recursive;\n    // processing submodules without processing contents of other directories makes no sense\n    if (processSubmodules && !recursive) {\n      throw new Error(\n        `Input property \"recursive\" must be true if \"processSubmodules\" is true.`\n      );\n    }\n    this.processSubmodules = processSubmodules;\n    this.unknown = unknown;\n    this.accessToken = accessToken;\n    this.ignoreFiles = ignoreFiles;\n    this.verbose = verbose;\n    this.maxConcurrency = maxConcurrency;\n    this.maxRetries = maxRetries;\n    this.headers = {\n      \"User-Agent\": \"langchain\",\n    };\n    this.caller = new AsyncCaller({\n      maxConcurrency,\n      maxRetries,\n      ...rest,\n    });\n    this.ignorePaths = ignorePaths;\n    if (ignorePaths) {\n      this.ignore = ignore().add(ignorePaths);\n    }\n    if (this.accessToken) {\n      this.headers = {\n        ...this.headers,\n        Authorization: `Bearer ${this.accessToken}`,\n      };\n    }\n  }\n\n  /**\n   * Extracts the owner, repository, and path from a GitHub URL.\n   * @param url The GitHub URL to extract information from.\n   * @returns An object containing the owner, repository, and path extracted from the GitHub URL.\n   */\n  private extractOwnerAndRepoAndPath(url: string): {\n    owner: string;\n    repo: string;\n    path: string;\n  } {\n    const match = url.match(\n      new RegExp(`${this.baseUrl}/([^/]+)/([^/]+)(/tree/[^/]+/(.+))?`, \"i\")\n    );\n\n    if (!match) {\n      throw new Error(\"Invalid GitHub URL format.\");\n    }\n\n    return { owner: match[1], repo: match[2], path: match[4] || \"\" };\n  }\n\n  /**\n   * Fetches the files from the GitHub repository and creates Document\n   * instances for each file. It also handles error handling based on the\n   * unknown handling option.\n   * @returns A promise that resolves to an array of Document instances.\n   */\n  public async load(): Promise<Document[]> {\n    this.log(\n      `Loading documents from ${this.baseUrl}/${this.owner}/${this.repo}/${this.initialPath}...`\n    );\n    // process repository without submodules\n    const documents: Document[] = (await this.processRepo()).map(\n      (fileResponse) =>\n        new Document({\n          pageContent: fileResponse.contents,\n          metadata: fileResponse.metadata,\n        })\n    );\n    if (this.processSubmodules) {\n      // process submodules\n      await this.getSubmoduleInfo();\n      for (const submoduleInfo of this.submoduleInfos) {\n        documents.push(...(await this.loadSubmodule(submoduleInfo)));\n      }\n    }\n    return documents;\n  }\n\n  /**\n   * Asynchronously streams documents from the entire GitHub repository.\n   * It is suitable for situations where processing large repositories in a memory-efficient manner is required.\n   * @yields Yields a Promise that resolves to a Document object for each file or submodule content found in the repository.\n   */\n  public async *loadAsStream(): AsyncGenerator<Document, void, undefined> {\n    this.log(\n      `Loading documents from ${this.baseUrl}/${this.owner}/${this.repo}/${this.initialPath}...`\n    );\n    yield* await this.processRepoAsStream(this.initialPath);\n\n    if (!this.processSubmodules) {\n      return;\n    }\n\n    await this.getSubmoduleInfo();\n    for (const submoduleInfo of this.submoduleInfos) {\n      yield* await this.loadSubmoduleAsStream(submoduleInfo);\n    }\n  }\n\n  /**\n   * Loads the information about Git submodules from the repository, if available.\n   */\n  private async getSubmoduleInfo(): Promise<void> {\n    this.log(\"Loading info about submodules...\");\n    // we have to fetch the files of the root directory to get the download url of the .gitmodules file\n    // however, we cannot reuse the files retrieved in processRepo() as initialPath may be != \"\"\n    // so it may be that we end up fetching this file list twice\n    const repoFiles = await this.fetchRepoFiles(\"\");\n    const gitmodulesFile = repoFiles.filter(\n      ({ name }) => name === \".gitmodules\"\n    )?.[0];\n    if (gitmodulesFile) {\n      const gitmodulesContent = await this.fetchFileContent({\n        download_url: gitmodulesFile.download_url,\n      } as GithubFile);\n      this.submoduleInfos = await this.parseGitmodules(gitmodulesContent);\n    } else {\n      this.submoduleInfos = [];\n    }\n    this.log(`Found ${this.submoduleInfos.length} submodules:`);\n    for (const submoduleInfo of this.submoduleInfos) {\n      this.log(JSON.stringify(submoduleInfo));\n    }\n  }\n\n  /**\n   * Parses the given content of a .gitmodules file. Furthermore, queries the current SHA ref of all submodules.\n   * Returns the submodule information as array.\n   * @param gitmodulesContent the content of a .gitmodules file\n   */\n  private async parseGitmodules(\n    gitmodulesContent: string\n  ): Promise<SubmoduleInfo[]> {\n    let validGitmodulesContent = gitmodulesContent;\n    // in case the .gitmodules file does not end with a newline, we add one to make the regex work\n    if (!validGitmodulesContent.endsWith(\"\\n\")) {\n      validGitmodulesContent += \"\\n\";\n    }\n    // catches the initial line of submodule entries\n    const submodulePattern = /\\[submodule \"(.*?)\"]\\n((\\s+.*?\\s*=\\s*.*?\\n)*)/g;\n    // catches the properties of a submodule\n    const keyValuePattern = /\\s+(.*?)\\s*=\\s*(.*?)\\s/g;\n\n    const submoduleInfos = [];\n    for (const [, name, propertyLines] of validGitmodulesContent.matchAll(\n      submodulePattern\n    )) {\n      if (!name || !propertyLines) {\n        throw new Error(\"Could not parse submodule entry\");\n      }\n      const submodulePropertyLines = propertyLines.matchAll(keyValuePattern);\n      let path;\n      let url;\n      for (const [, key, value] of submodulePropertyLines) {\n        if (!key || !value) {\n          throw new Error(\n            `Could not parse key/value pairs for submodule ${name}`\n          );\n        }\n        switch (key) {\n          case \"path\":\n            path = value;\n            break;\n          case \"url\":\n            url = value;\n            if (url.endsWith(\".git\")) {\n              url = url.substring(0, url.length - 4);\n            }\n            break;\n          default:\n          // ignoring unused keys\n        }\n      }\n      if (!path || !url) {\n        throw new Error(`Missing properties for submodule ${name}`);\n      }\n      // fetch the current ref of the submodule\n      const files = await this.fetchRepoFiles(path);\n      const submoduleInfo: SubmoduleInfo = {\n        name,\n        path,\n        url,\n        ref: files[0].sha,\n      };\n      submoduleInfos.push(submoduleInfo);\n    }\n    return submoduleInfos;\n  }\n\n  /**\n   * Loads the documents of the given submodule. Uses the same parameters as for the current repository.\n   * External submodules, i.e. submodules pointing to another GitHub instance, are ignored.\n   * @param submoduleInfo the info about the submodule to be loaded\n   */\n  private async loadSubmodule(\n    submoduleInfo: SubmoduleInfo\n  ): Promise<Document[]> {\n    if (!submoduleInfo.url.startsWith(this.baseUrl)) {\n      this.log(`Ignoring external submodule ${submoduleInfo.url}.`);\n      return [];\n    } else if (!submoduleInfo.path.startsWith(this.initialPath)) {\n      this.log(\n        `Ignoring submodule ${submoduleInfo.url}, as it is not on initial path.`\n      );\n      return [];\n    } else {\n      this.log(\n        `Accessing submodule ${submoduleInfo.name} (${submoduleInfo.url})...`\n      );\n      return new GithubRepoLoader(submoduleInfo.url, {\n        accessToken: this.accessToken,\n        apiUrl: this.apiUrl,\n        baseUrl: this.baseUrl,\n        branch: submoduleInfo.ref,\n        recursive: this.recursive,\n        processSubmodules: this.processSubmodules,\n        unknown: this.unknown,\n        ignoreFiles: this.ignoreFiles,\n        ignorePaths: this.ignorePaths,\n        verbose: this.verbose,\n        maxConcurrency: this.maxConcurrency,\n        maxRetries: this.maxRetries,\n      }).load();\n    }\n  }\n\n  /**\n   * Asynchronously processes and streams the contents of a specified submodule in the GitHub repository.\n   * @param submoduleInfo the info about the submodule to be loaded\n   * @yields Yields a Promise that resolves to a Document object for each file found in the submodule.\n   */\n  private async *loadSubmoduleAsStream(\n    submoduleInfo: SubmoduleInfo\n  ): AsyncGenerator<Document, void, undefined> {\n    if (!submoduleInfo.url.startsWith(this.baseUrl)) {\n      this.log(`Ignoring external submodule ${submoduleInfo.url}.`);\n      yield* [];\n    }\n\n    if (!submoduleInfo.path.startsWith(this.initialPath)) {\n      this.log(\n        `Ignoring submodule ${submoduleInfo.url}, as it is not on initial path.`\n      );\n      yield* [];\n    }\n\n    this.log(\n      `Accessing submodule ${submoduleInfo.name} (${submoduleInfo.url})...`\n    );\n    const submoduleLoader = new GithubRepoLoader(submoduleInfo.url, {\n      accessToken: this.accessToken,\n      baseUrl: this.baseUrl,\n      apiUrl: this.apiUrl,\n      branch: submoduleInfo.ref,\n      recursive: this.recursive,\n      processSubmodules: this.processSubmodules,\n      unknown: this.unknown,\n      ignoreFiles: this.ignoreFiles,\n      ignorePaths: this.ignorePaths,\n      verbose: this.verbose,\n      maxConcurrency: this.maxConcurrency,\n      maxRetries: this.maxRetries,\n    });\n\n    yield* await submoduleLoader.processRepoAsStream(submoduleInfo.path);\n  }\n\n  /**\n   * Determines whether a file or directory should be ignored based on its\n   * path and type.\n   * @param path The path of the file or directory.\n   * @param fileType The type of the file or directory.\n   * @returns A boolean indicating whether the file or directory should be ignored.\n   */\n  protected shouldIgnore(path: string, fileType: string): boolean {\n    if (fileType !== \"dir\" && isBinaryPath(path)) {\n      return true;\n    }\n    if (this.ignore !== undefined) {\n      return this.ignore.ignores(path);\n    }\n    return (\n      fileType !== \"dir\" &&\n      this.ignoreFiles.some((pattern) => {\n        if (typeof pattern === \"string\") {\n          return path === pattern;\n        }\n\n        try {\n          return pattern.test(path);\n        } catch {\n          throw new Error(`Unknown ignore file pattern: ${pattern}`);\n        }\n      })\n    );\n  }\n\n  /**\n   * Takes the file info and wrap it in a promise that will resolve to the file content and metadata\n   * @param file\n   * @returns\n   */\n  private async fetchFileContentWrapper(\n    file: GithubFile\n  ): Promise<GetContentResponse> {\n    const fileContent = await this.fetchFileContent(file).catch((error) => {\n      this.handleError(`Failed wrap file content: ${file}, ${error}`);\n    });\n    return {\n      contents: fileContent || \"\",\n      metadata: {\n        source: file.path,\n        repository: `${this.baseUrl}/${this.owner}/${this.repo}`,\n        branch: this.branch,\n      },\n    };\n  }\n\n  /**\n   * Maps a list of files / directories to a list of promises that will fetch the file / directory contents\n   */\n  private async getCurrentDirectoryFilePromises(\n    files: GithubFile[]\n  ): Promise<Promise<GetContentResponse>[]> {\n    const currentDirectoryFilePromises: Promise<GetContentResponse>[] = [];\n    // Directories have nested files / directories, which is why this is a list of promises of promises\n    const currentDirectoryDirectoryPromises: Promise<\n      Promise<GetContentResponse>[]\n    >[] = [];\n\n    for (const file of files) {\n      if (file.type !== \"dir\" && this.shouldIgnore(file.path, file.type)) {\n        continue;\n      }\n      if (file.type === \"file\" && file.size === 0) {\n        // this is a submodule. ignoring for the moment. submodule processing is done separately\n        continue;\n      }\n      if (file.type !== \"dir\") {\n        try {\n          currentDirectoryFilePromises.push(this.fetchFileContentWrapper(file));\n        } catch (e) {\n          this.handleError(`Failed to fetch file content: ${file.path}, ${e}`);\n        }\n      } else if (this.recursive) {\n        currentDirectoryDirectoryPromises.push(\n          this.processDirectory(file.path)\n        );\n      }\n    }\n\n    const curDirDirectories: Promise<GetContentResponse>[][] =\n      await Promise.all(currentDirectoryDirectoryPromises);\n\n    return [...currentDirectoryFilePromises, ...curDirDirectories.flat()];\n  }\n\n  /**\n   * Begins the process of fetching the contents of the repository\n   */\n  private async processRepo(): Promise<GetContentResponse[]> {\n    try {\n      // Get the list of file / directory names in the root directory\n      const files = await this.fetchRepoFiles(this.initialPath);\n      // Map the file / directory paths to promises that will fetch the file / directory contents\n      const currentDirectoryFilePromises =\n        await this.getCurrentDirectoryFilePromises(files);\n      return Promise.all(currentDirectoryFilePromises);\n    } catch (error) {\n      this.handleError(\n        `Failed to process directory: ${this.initialPath}, ${error}`\n      );\n      return Promise.reject(error);\n    }\n  }\n\n  /**\n   * Asynchronously processes the contents of the entire GitHub repository,\n   * streaming each file as a Document object.\n   * @param path The path of the directory to process.\n   * @yields Yields a Promise that resolves to a Document object for each file found in the repository.\n   */\n  private async *processRepoAsStream(\n    path: string\n  ): AsyncGenerator<Document, void, undefined> {\n    const files = await this.fetchRepoFiles(path);\n    for (const file of files) {\n      if (file.type !== \"dir\" && this.shouldIgnore(file.path, file.type)) {\n        continue;\n      }\n\n      if (file.type === \"file\") {\n        try {\n          const fileResponse = await this.fetchFileContentWrapper(file);\n\n          yield new Document({\n            pageContent: fileResponse.contents,\n            metadata: fileResponse.metadata,\n          });\n        } catch (error) {\n          this.handleError(\n            `Failed to fetch file content: ${file.path}, ${error}`\n          );\n        }\n      } else if (this.recursive) {\n        yield* await this.processDirectoryAsStream(file.path);\n      }\n    }\n  }\n\n  /**\n   * Fetches the contents of a directory and maps the file / directory paths\n   * to promises that will fetch the file / directory contents.\n   * @param path The path of the directory to process.\n   * @returns A promise that resolves to an array of promises that will fetch the file / directory contents.\n   */\n  private async processDirectory(\n    path: string\n  ): Promise<Promise<GetContentResponse>[]> {\n    try {\n      const files = await this.fetchRepoFiles(path);\n      return this.getCurrentDirectoryFilePromises(files);\n    } catch (error) {\n      this.handleError(`Failed to process directory: ${path}, ${error}`);\n      return Promise.reject(error);\n    }\n  }\n\n  /**\n   * Asynchronously processes the contents of a given directory in the GitHub repository,\n   * streaming each file as a Document object.\n   * @param path The path of the directory to process.\n   * @yields Yields a Promise that resolves to a Document object for each file in the directory.\n   */\n  private async *processDirectoryAsStream(\n    path: string\n  ): AsyncGenerator<Document, void, undefined> {\n    const files = await this.fetchRepoFiles(path);\n\n    for (const file of files) {\n      if (file.type !== \"dir\" && this.shouldIgnore(file.path, file.type)) {\n        continue;\n      }\n\n      if (file.type === \"file\") {\n        try {\n          const fileResponse = await this.fetchFileContentWrapper(file);\n\n          yield new Document({\n            pageContent: fileResponse.contents,\n            metadata: fileResponse.metadata,\n          });\n        } catch {\n          this.handleError(`Failed to fetch file content: ${file.path}`);\n        }\n      } else if (this.recursive) {\n        yield* await this.processDirectoryAsStream(file.path);\n      }\n    }\n  }\n\n  /**\n   * Fetches the files from a GitHub repository.\n   * If the path denotes a single file, the resulting array contains only one element.\n   * @param path The path of the repository to fetch the files from.\n   * @returns A promise that resolves to an array of GithubFile instances.\n   */\n  private async fetchRepoFiles(path: string): Promise<GithubFile[]> {\n    const url = `${this.apiUrl}/repos/${this.owner}/${\n      this.repo\n    }/contents/${encodeURIComponent(path)}?ref=${this.branch}`;\n    return this.caller.call(async () => {\n      this.log(`Fetching ${url}`);\n      const response = await fetch(url, { headers: this.headers });\n      const data = await response.json();\n      if (!response.ok) {\n        throw new Error(\n          `Unable to fetch repository files: ${\n            response.status\n          } ${JSON.stringify(data)}`\n        );\n      }\n\n      if (Array.isArray(data)) {\n        return data as GithubFile[];\n      } else {\n        return [data as GithubFile];\n      }\n    });\n  }\n\n  /**\n   * Fetches the content of a file from a GitHub repository.\n   * @param file The file to fetch the content from.\n   * @returns A promise that resolves to the content of the file.\n   */\n  private async fetchFileContent(file: GithubFile): Promise<string> {\n    return this.caller.call(async () => {\n      this.log(`Fetching ${file.download_url}`);\n      const response = await fetch(file.download_url, {\n        headers: this.headers,\n      });\n      return response.text();\n    });\n  }\n\n  /**\n   * Handles errors based on the unknown handling option.\n   * @param message The error message.\n   * @returns void\n   */\n  private handleError(message: string): void {\n    switch (this.unknown) {\n      case UnknownHandling.Ignore:\n        break;\n      case UnknownHandling.Warn:\n        console.warn(message);\n        break;\n      case UnknownHandling.Error:\n        throw new Error(message);\n      default:\n        throw new Error(`Unknown unknown handling: ${this.unknown}`);\n    }\n  }\n\n  /**\n   * Logs the given message to the console, if parameter 'verbose' is set to true.\n   * @param message the message to be logged.\n   */\n  private log(message: string): void {\n    if (this.verbose) {\n      console.log(message);\n    }\n  }\n}\n"],"mappings":"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"}