{"version":3,"file":"github.cjs","names":["binaryExtensions","extname","BaseDocumentLoader","UnknownHandling","AsyncCaller","Document"],"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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"}