Skip to content

Commit 9ccfb09

Browse files
hntrleg-renovate-user
authored andcommitted
fix(community): URL encode paths in GitHub document loader (#8860)
Co-authored-by: Dylan Dignan <dylan.dignan@epicgames.com>
1 parent 938c553 commit 9ccfb09

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

libs/langchain-community/src/document_loaders/tests/github.test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,56 @@ describe("GithubRepoLoader recursion", () => {
6161
).toThrow();
6262
});
6363
});
64+
65+
describe("GithubRepoLoader URL encoding", () => {
66+
test("Should properly encode special characters in directory paths", async () => {
67+
// Mock fetch to capture the URLs being called
68+
const mockFetch = jest.fn().mockImplementation((url) => {
69+
// Check that special characters are properly encoded in the URL
70+
expect(url).toContain("src%2Fapp%2F%255Fmeta"); // The full encoded path
71+
72+
return Promise.resolve({
73+
ok: true,
74+
json: () =>
75+
Promise.resolve([
76+
{
77+
name: "%5Fmeta",
78+
path: "src/app/%5Fmeta",
79+
type: "dir",
80+
size: 0,
81+
url: "https://api.github.com/repos/test/test/contents/src/app/%5Fmeta",
82+
html_url: "",
83+
sha: "abc123",
84+
git_url: "",
85+
download_url: "",
86+
_links: {
87+
self: "",
88+
git: "",
89+
html: "",
90+
},
91+
},
92+
]),
93+
});
94+
});
95+
96+
global.fetch = mockFetch as any;
97+
98+
const loader = new GithubRepoLoader(
99+
"https://github.com/test/test/tree/main/src/app/%5Fmeta",
100+
{
101+
branch: "main",
102+
recursive: false,
103+
unknown: "warn",
104+
}
105+
);
106+
107+
// This should call fetchRepoFiles with "src/app/%5Fmeta" path
108+
await loader.load();
109+
110+
// Verify that fetch was called with properly encoded URL
111+
expect(mockFetch).toHaveBeenCalledWith(
112+
expect.stringContaining("contents/src%2Fapp%2F%255Fmeta"),
113+
expect.any(Object)
114+
);
115+
});
116+
});

libs/langchain-community/src/document_loaders/web/github.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,9 @@ export class GithubRepoLoader
647647
* @returns A promise that resolves to an array of GithubFile instances.
648648
*/
649649
private async fetchRepoFiles(path: string): Promise<GithubFile[]> {
650-
const url = `${this.apiUrl}/repos/${this.owner}/${this.repo}/contents/${path}?ref=${this.branch}`;
650+
const url = `${this.apiUrl}/repos/${this.owner}/${
651+
this.repo
652+
}/contents/${encodeURIComponent(path)}?ref=${this.branch}`;
651653
return this.caller.call(async () => {
652654
this.log(`Fetching ${url}`);
653655
const response = await fetch(url, { headers: this.headers });

0 commit comments

Comments
 (0)