Skip to content

Commit 99d09cf

Browse files
committed
feat: add source resolution helpers
1 parent 4ecc0f1 commit 99d09cf

1 file changed

Lines changed: 80 additions & 0 deletions

File tree

src/source.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { Octokit } from "octokit";
2+
3+
const GITHUB_OWNER = "typesense" as const;
4+
const GITHUB_REPO = "typesense" as const;
5+
const GITHUB_RAW_BASE_URL =
6+
`https://raw.githubusercontent.com/${GITHUB_OWNER}/${GITHUB_REPO}` as const;
7+
const GITHUB_API_VERSION = "2022-11-28" as const;
8+
const octokit = new Octokit();
9+
10+
export function resolveSourcePath(rootDir: string, filePath: string): string {
11+
const normalizedRootDir = normalizeRepoPath(rootDir);
12+
const normalizedFilePath = normalizeRepoPath(filePath);
13+
14+
if (normalizedFilePath.length === 0) {
15+
throw new Error("Source file path cannot be empty.");
16+
}
17+
18+
if (
19+
normalizedFilePath.startsWith("http://") ||
20+
normalizedFilePath.startsWith("https://")
21+
) {
22+
return normalizedFilePath;
23+
}
24+
25+
if (normalizedRootDir.length === 0) {
26+
return normalizedFilePath;
27+
}
28+
29+
return normalizeRepoPath(`${normalizedRootDir}/${normalizedFilePath}`);
30+
}
31+
32+
export function resolveRawGithubUrl(
33+
sourceBranch: string,
34+
sourcePath: string,
35+
): string {
36+
const normalizedSourcePath = normalizeRepoPath(sourcePath);
37+
if (normalizedSourcePath.length === 0) {
38+
throw new Error("Source path cannot be empty.");
39+
}
40+
return `${GITHUB_RAW_BASE_URL}/${sourceBranch}/${normalizedSourcePath}`;
41+
}
42+
43+
export async function listSourceFiles(
44+
sourceBranch: string,
45+
rootDir: string,
46+
extensions: readonly string[],
47+
): Promise<readonly string[]> {
48+
const response = await octokit.rest.git.getTree({
49+
owner: GITHUB_OWNER,
50+
repo: GITHUB_REPO,
51+
tree_sha: sourceBranch,
52+
recursive: "1",
53+
headers: {
54+
"X-GitHub-Api-Version": GITHUB_API_VERSION,
55+
},
56+
});
57+
58+
if (response.data.truncated === true) {
59+
throw new Error(`GitHub tree response for ${sourceBranch} was truncated.`);
60+
}
61+
62+
const normalizedRootDir = normalizeRepoPath(rootDir);
63+
const rootPrefix =
64+
normalizedRootDir.length === 0 ? "" : `${normalizedRootDir}/`;
65+
66+
return response.data.tree
67+
.filter((entry) => entry.type === "blob")
68+
.map((entry) => entry.path)
69+
.filter((filePath): filePath is string => filePath !== undefined)
70+
.filter(
71+
(filePath) => rootPrefix.length === 0 || filePath.startsWith(rootPrefix),
72+
)
73+
.filter((filePath) =>
74+
extensions.some((extension) => filePath.endsWith(extension)),
75+
);
76+
}
77+
78+
function normalizeRepoPath(value: string): string {
79+
return value.replaceAll("\\", "/").replace(/^\/+/, "").replace(/\/+$/, "");
80+
}

0 commit comments

Comments
 (0)