Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import tseslint from 'typescript-eslint';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';

export default [
{ ignores: ['**/dist', '**/assets', 'vscode-web/lib', '**/vs', '**/vscode.proposed.d.ts'] },
{ ignores: ['**/dist', '**/out', '**/assets', 'vscode-web/lib', '**/vs', '**/vscode.proposed.d.ts'] },
...tseslint.configs.recommended,
jsdoc.configs['flat/recommended-typescript'],
eslintPluginPrettierRecommended,
Expand Down
149 changes: 91 additions & 58 deletions extensions/github1s/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion extensions/github1s/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -637,9 +637,10 @@
"js-base64": "^3.7.2",
"json-stable-stringify": "^1.0.1",
"match-sorter": "^6.3.1",
"minimatch": "^9.0.9",
"p-finally": "^3.0.0",
"process": "^0.11.10",
"query-string": "^7.1.1"
"query-string": "^9.5.0"
},
"devDependencies": {
"@types/vscode": "^1.96.0",
Expand Down
36 changes: 33 additions & 3 deletions extensions/github1s/src/adapters/github1s/data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { toUint8Array } from 'js-base64';
import { matchSorter } from 'match-sorter';
import { FILE_BLAME_QUERY } from './graphql';
import { GitHubFetcher } from './fetcher';
import { getGitHubTextSearchResults, getSearchcodeTextSearchResults } from './search';
import { SourcegraphDataSource } from '../sourcegraph/data-source';
import { decorate, memorize } from '@/helpers/func';
import { normalizePath, trimStart, concatPath, isString } from '@/helpers/util';
Expand Down Expand Up @@ -105,10 +106,29 @@ export class GitHub1sDataSource extends DataSource {
@trySourcegraphApiFirst
async provideDirectory(repoFullName: string, ref: string, path: string, recursive = false): Promise<Directory> {
const fetcher = GitHubFetcher.getInstance();
const repositoryParams = parseRepoFullName(repoFullName);
if (recursive) {
const response = await fetcher
.request('GET /repos/{owner}/{repo}/git/tree-file-list/{ref}', { ref, ...repositoryParams })
.catch(() => null);
const filePaths = response?.data;
if (Array.isArray(filePaths) && filePaths.every(isString)) {
const directoryPath = path.split('/').filter(Boolean).join('/');
const directoryPrefix = directoryPath ? `${directoryPath}/` : '';
const entries: DirectoryEntry[] = filePaths
.filter((filePath: string) => filePath.startsWith(directoryPrefix))
.map((filePath: string) => ({
path: concatPath(path, filePath.slice(directoryPrefix.length)),
type: FileType.File,
}));
return { entries, truncated: false };
}
}

const encodedPath = trimStart(encodeFilePath(path), '/');
// github api will return all files if `recursive` exists, even the value if false
const recursiveParams = recursive ? { recursive } : {};
const requestParams = { ref, path: encodedPath, ...parseRepoFullName(repoFullName), ...recursiveParams };
const requestParams = { ref, path: encodedPath, ...repositoryParams, ...recursiveParams };
const { data } = await fetcher.request('GET /repos/{owner}/{repo}/git/trees/{ref}:{path}', requestParams);
const parseTreeItem = (treeItem): DirectoryEntry => ({
path: concatPath(path, treeItem.path),
Expand Down Expand Up @@ -176,7 +196,7 @@ export class GitHub1sDataSource extends DataSource {
const response = await fetcher.request(requestUrl, requestParams).catch(reject);
response?.data?.ref && this.matchedRefsMap.get(repoFullName)?.push(response.data.ref);
const result = response?.data || { ref: 'HEAD', path: '/' };
return resolve({ ...result, path: normalizePath(result.path) });
return resolve({ ...result, path: normalizePath(result.path || '') });
});
this.refPathPromiseMap.set(mapKey, refPathPromise);
}
Expand Down Expand Up @@ -229,13 +249,23 @@ export class GitHub1sDataSource extends DataSource {
return tags.find((item) => item.name === tagName) || null;
}

@trySourcegraphApiFirst
async provideTextSearchResults(
repoFullName: string,
ref: string,
query: TextSearchQuery,
options: TextSearchOptions,
): Promise<TextSearchResults> {
return sourcegraphDataSource.provideTextSearchResults(repoFullName, ref, query, options);
try {
// Prefer using the searchcode.com API, and fallback to GitHub API if it's unavailable.
return await getSearchcodeTextSearchResults(`${GITHUB_ORIGIN}/${repoFullName}`, query, options);
} catch {
// Now Github API is blocked by CORS, so we use a CF Worker to proxy this request temporarily
// Proxy Worker source code: functions/api/github/search/code.ts
// Also see https://github.com/orgs/community/discussions/206576
const baseUrl = `${self.location.origin}/api/github`;
return getGitHubTextSearchResults(GitHubFetcher.getInstance().request, baseUrl, repoFullName, query, options);
}
}

@trySourcegraphApiFirst
Expand Down
5 changes: 3 additions & 2 deletions extensions/github1s/src/adapters/github1s/fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,16 @@ export class GitHubFetcher {

this._request = octokit.request;
this.request = Object.assign((...args: Parameters<Octokit['request']>) => {
return octokit.request(...args).catch(async (error) => {
return this._request!(...args).catch(async (error) => {
const errorStatus = error?.response?.status as number | undefined;
const repoNotFound = errorStatus === 404 && !(await this.resolveCurrentRepo());
if ((errorStatus && [401, 403].includes(errorStatus)) || repoNotFound) {
// maybe we have to acquire github access token to continue
const message = detectErrorMessage(error?.response, !!accessToken);
const message = detectErrorMessage(error?.response, !!GitHubTokenManager.getInstance().getToken());
await GitHub1sAuthenticationView.getInstance().open(message, true);
return this._request!(...args);
}
throw error;
});
}, this._request);

Expand Down
Loading
Loading