@gitkraken/core-gitlens 0.7.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -1
- package/dist/git/cache.d.ts +18 -5
- package/dist/git/cache.js +26 -8
- package/dist/git/cache.js.map +1 -1
- package/dist/git/context.d.ts +5 -1
- package/dist/git/context.js.map +1 -1
- package/dist/git/errors.d.ts +28 -1
- package/dist/git/errors.js +45 -1
- package/dist/git/errors.js.map +1 -1
- package/dist/git/providers/branches.d.ts +5 -1
- package/dist/git/providers/commits.d.ts +24 -1
- package/dist/git/providers/config.d.ts +7 -1
- package/dist/git/providers/operations.d.ts +6 -0
- package/dist/git/providers/provider.d.ts +17 -0
- package/dist/git/providers/refs.d.ts +38 -3
- package/dist/git/providers/revision.d.ts +5 -1
- package/dist/git/providers/staging.d.ts +12 -0
- package/dist/git/providers/worktrees.d.ts +23 -3
- package/dist/git/run.types.d.ts +6 -0
- package/dist/git-cli/cliGitProvider.d.ts +17 -1
- package/dist/git-cli/cliGitProvider.js +37 -1
- package/dist/git-cli/cliGitProvider.js.map +1 -1
- package/dist/git-cli/exec/git.d.ts +12 -2
- package/dist/git-cli/exec/git.js +48 -17
- package/dist/git-cli/exec/git.js.map +1 -1
- package/dist/git-cli/exec/gitQueue.d.ts +4 -1
- package/dist/git-cli/exec/gitQueue.js +1 -1
- package/dist/git-cli/exec/gitQueue.js.map +1 -1
- package/dist/git-cli/providers/branches.d.ts +10 -1
- package/dist/git-cli/providers/branches.js +15 -8
- package/dist/git-cli/providers/branches.js.map +1 -1
- package/dist/git-cli/providers/commits.d.ts +23 -1
- package/dist/git-cli/providers/commits.js +57 -8
- package/dist/git-cli/providers/commits.js.map +1 -1
- package/dist/git-cli/providers/config.js +4 -3
- package/dist/git-cli/providers/config.js.map +1 -1
- package/dist/git-cli/providers/operations.d.ts +1 -0
- package/dist/git-cli/providers/operations.js +39 -3
- package/dist/git-cli/providers/operations.js.map +1 -1
- package/dist/git-cli/providers/patch.js +20 -41
- package/dist/git-cli/providers/patch.js.map +1 -1
- package/dist/git-cli/providers/pausedOperations.js +2 -2
- package/dist/git-cli/providers/pausedOperations.js.map +1 -1
- package/dist/git-cli/providers/refs.d.ts +15 -3
- package/dist/git-cli/providers/refs.js +115 -10
- package/dist/git-cli/providers/refs.js.map +1 -1
- package/dist/git-cli/providers/revision.d.ts +3 -1
- package/dist/git-cli/providers/revision.js +9 -5
- package/dist/git-cli/providers/revision.js.map +1 -1
- package/dist/git-cli/providers/staging.d.ts +8 -0
- package/dist/git-cli/providers/staging.js +59 -7
- package/dist/git-cli/providers/staging.js.map +1 -1
- package/dist/git-cli/providers/worktrees.d.ts +31 -2
- package/dist/git-cli/providers/worktrees.js +75 -7
- package/dist/git-cli/providers/worktrees.js.map +1 -1
- package/dist/ipc/discovery.js +1 -1
- package/dist/plus/agents/providers/claudeCodeTranscript.js +6 -6
- package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -1
- package/dist/plus/ai/providers/openAICompatibleProviderBase.js +1 -1
- package/dist/plus/git-github/api/github.d.ts +64 -3
- package/dist/plus/git-github/api/github.js +237 -24
- package/dist/plus/git-github/api/github.js.map +1 -1
- package/dist/plus/git-github/providers/github/branches.d.ts +3 -1
- package/dist/plus/git-github/providers/github/branches.js +2 -1
- package/dist/plus/git-github/providers/github/branches.js.map +1 -1
- package/dist/plus/git-github/providers/github/refs.d.ts +10 -3
- package/dist/plus/git-github/providers/github/refs.js +4 -4
- package/dist/plus/git-github/providers/github/refs.js.map +1 -1
- package/dist/plus/git-github/providers/github/revision.d.ts +3 -1
- package/dist/plus/git-github/providers/github/revision.js +1 -1
- package/dist/plus/git-github/providers/github/revision.js.map +1 -1
- package/dist/plus/integrations/collectionMetadata.d.ts +48 -3
- package/dist/plus/integrations/collectionMetadata.js +138 -8
- package/dist/plus/integrations/collectionMetadata.js.map +1 -1
- package/dist/plus/integrations/errors.d.ts +3 -1
- package/dist/plus/integrations/errors.js +7 -3
- package/dist/plus/integrations/errors.js.map +1 -1
- package/dist/plus/integrations/index.d.ts +6 -3
- package/dist/plus/integrations/index.js.map +1 -1
- package/dist/plus/integrations/integrationService.d.ts +36 -10
- package/dist/plus/integrations/integrationService.js +16 -3
- package/dist/plus/integrations/integrationService.js.map +1 -1
- package/dist/plus/integrations/manager.d.ts +107 -37
- package/dist/plus/integrations/models/gitHostIntegration.d.ts +129 -14
- package/dist/plus/integrations/models/gitHostIntegration.js +142 -18
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
- package/dist/plus/integrations/models/integration.d.ts +117 -11
- package/dist/plus/integrations/models/integration.js +175 -13
- package/dist/plus/integrations/models/integration.js.map +1 -1
- package/dist/plus/integrations/models/issuesIntegration.d.ts +18 -5
- package/dist/plus/integrations/models/issuesIntegration.js +42 -10
- package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
- package/dist/plus/integrations/providers/azure/azure.d.ts +1 -1
- package/dist/plus/integrations/providers/azure/azure.js +14 -18
- package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
- package/dist/plus/integrations/providers/azure/models.d.ts +29 -0
- package/dist/plus/integrations/providers/azure/models.js +112 -1
- package/dist/plus/integrations/providers/azure/models.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOps.d.ts +73 -3
- package/dist/plus/integrations/providers/azureDevOps.js +117 -3
- package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOpsServer.js +2 -1
- package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts +61 -0
- package/dist/plus/integrations/providers/bitbucket/bitbucket.js +165 -23
- package/dist/plus/integrations/providers/bitbucket/bitbucket.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket/models.d.ts +6 -1
- package/dist/plus/integrations/providers/bitbucket/models.js +4 -3
- package/dist/plus/integrations/providers/bitbucket/models.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js +2 -2
- package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket-server.d.ts +48 -2
- package/dist/plus/integrations/providers/bitbucket-server.js +51 -1
- package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket.d.ts +45 -2
- package/dist/plus/integrations/providers/bitbucket.js +41 -2
- package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
- package/dist/plus/integrations/providers/github.d.ts +49 -5
- package/dist/plus/integrations/providers/github.js +102 -7
- package/dist/plus/integrations/providers/github.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab/gitlab.d.ts +35 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.js +132 -15
- package/dist/plus/integrations/providers/gitlab/gitlab.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab/models.d.ts +1 -0
- package/dist/plus/integrations/providers/gitlab/models.js +1 -1
- package/dist/plus/integrations/providers/gitlab/models.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab.d.ts +49 -2
- package/dist/plus/integrations/providers/gitlab.js +80 -4
- package/dist/plus/integrations/providers/gitlab.js.map +1 -1
- package/dist/plus/integrations/providers/jira-server.d.ts +3 -3
- package/dist/plus/integrations/providers/jira-server.js +5 -8
- package/dist/plus/integrations/providers/jira-server.js.map +1 -1
- package/dist/plus/integrations/providers/jira.d.ts +9 -0
- package/dist/plus/integrations/providers/jira.js +13 -1
- package/dist/plus/integrations/providers/jira.js.map +1 -1
- package/dist/plus/integrations/providers/linear.js +1 -1
- package/dist/plus/integrations/providers/models.d.ts +13 -2
- package/dist/plus/integrations/providers/models.js +11 -1
- package/dist/plus/integrations/providers/models.js.map +1 -1
- package/dist/plus/integrations/providers/providerErrors.d.ts +9 -1
- package/dist/plus/integrations/providers/providerErrors.js +10 -1
- package/dist/plus/integrations/providers/providerErrors.js.map +1 -1
- package/dist/plus/integrations/providers/providersApi.d.ts +60 -1
- package/dist/plus/integrations/providers/providersApi.js +137 -2
- package/dist/plus/integrations/providers/providersApi.js.map +1 -1
- package/dist/plus/integrations/providers/utils/providerPaging.d.ts +42 -0
- package/dist/plus/integrations/providers/utils/providerPaging.js +58 -1
- package/dist/plus/integrations/providers/utils/providerPaging.js.map +1 -1
- package/dist/plus/integrations/providers/utils.d.ts +1 -1
- package/dist/plus/integrations/reads/broaden.js +1 -1
- package/dist/plus/integrations/reads/context.d.ts +1 -1
- package/dist/plus/integrations/reads/counts.js +1 -1
- package/dist/plus/integrations/reads/currentAccount.d.ts +35 -0
- package/dist/plus/integrations/reads/currentAccount.js +46 -0
- package/dist/plus/integrations/reads/currentAccount.js.map +1 -0
- package/dist/plus/integrations/reads/drains.d.ts +5 -2
- package/dist/plus/integrations/reads/drains.js +8 -4
- package/dist/plus/integrations/reads/drains.js.map +1 -1
- package/dist/plus/integrations/reads/hierarchy.js +1 -1
- package/dist/plus/integrations/reads/hierarchy.utils.js +1 -1
- package/dist/plus/integrations/reads/issueBatch.d.ts +72 -12
- package/dist/plus/integrations/reads/issueBatch.js +193 -48
- package/dist/plus/integrations/reads/issueBatch.js.map +1 -1
- package/dist/plus/integrations/reads/issueTracker.js +1 -1
- package/dist/plus/integrations/reads/issues.js +1 -1
- package/dist/plus/integrations/reads/pullRequestBatch.d.ts +57 -0
- package/dist/plus/integrations/reads/pullRequestBatch.js +80 -0
- package/dist/plus/integrations/reads/pullRequestBatch.js.map +1 -0
- package/dist/plus/integrations/reads/pullRequestBranches.d.ts +58 -0
- package/dist/plus/integrations/reads/pullRequestBranches.js +111 -0
- package/dist/plus/integrations/reads/pullRequestBranches.js.map +1 -0
- package/dist/plus/integrations/reads/pullRequests.js +3 -3
- package/dist/plus/integrations/reads/pullRequests.js.map +1 -1
- package/dist/plus/integrations/reads/resolveRepository.js +1 -1
- package/dist/plus/integrations/reads/sweeps.js +4 -4
- package/dist/plus/integrations/reads/sweeps.js.map +1 -1
- package/dist/plus/integrations/results.d.ts +87 -6
- package/dist/plus/integrations/results.js +9 -2
- package/dist/plus/integrations/results.js.map +1 -1
- package/dist/utils/env/node/exec.js +3 -3
- package/dist/utils/env/node/exec.js.map +1 -1
- package/docs/integrations.md +175 -35
- package/docs/kepler-git-write-api-parity.md +239 -0
- package/docs/kepler-read-api-parity.md +75 -28
- package/package.json +1 -1
- package/dist/plus/integrations/reads/trackerIssue.d.ts +0 -33
- package/dist/plus/integrations/reads/trackerIssue.js +0 -60
- package/dist/plus/integrations/reads/trackerIssue.js.map +0 -1
|
@@ -7,7 +7,7 @@ import { trace } from "../../../utils/decorators/log.js";
|
|
|
7
7
|
import { parseUri } from "../../../utils/uri.js";
|
|
8
8
|
import { createRevisionRange, getRevisionRangeParts, isRevisionRange, isSha, isUncommitted } from "../../../git/utils/revision.utils.js";
|
|
9
9
|
import __decorate from "../../../_virtual/@oxc-project+runtime/helpers/esm/decorate.js";
|
|
10
|
-
import { AuthenticationError, RequestClientError, RequestNotFoundError, RequestRateLimitError } from "../../../git/errors.js";
|
|
10
|
+
import { AuthenticationError, RequestClientError, RequestNotFoundError, RequestRateLimitError, reportRequestFailure } from "../../../git/errors.js";
|
|
11
11
|
import { Emitter } from "../../../utils/event.js";
|
|
12
12
|
import { fromString, satisfies } from "../../../utils/version.js";
|
|
13
13
|
import { maybeStopWatch } from "../../../utils/stopwatch.js";
|
|
@@ -302,6 +302,21 @@ repository {
|
|
|
302
302
|
url
|
|
303
303
|
}
|
|
304
304
|
`;
|
|
305
|
+
/**
|
|
306
|
+
* What an alias's own errors say about its slot in an {@link AliasedGraphqlResult}: `'absent'` only when its node
|
|
307
|
+
* is null and every error on it is NOT_FOUND; a rejection when a node arrived with an error, or on any other error
|
|
308
|
+
* (even a NOT_FOUND nested under the node), since neither is trustworthy; `undefined` when the alias has no errors.
|
|
309
|
+
*/
|
|
310
|
+
function getAliasErrorVerdict(errors, alias, node) {
|
|
311
|
+
const aliasErrors = errors.filter((e) => e.path?.[0] === alias);
|
|
312
|
+
if (aliasErrors.length === 0) return void 0;
|
|
313
|
+
if (node == null && aliasErrors.every((e) => e.type === "NOT_FOUND")) return "absent";
|
|
314
|
+
const primary = aliasErrors.find((e) => e.type !== "NOT_FOUND") ?? aliasErrors[0];
|
|
315
|
+
return {
|
|
316
|
+
status: "rejected",
|
|
317
|
+
reason: new Error(primary.message)
|
|
318
|
+
};
|
|
319
|
+
}
|
|
305
320
|
var GitHubApi = class {
|
|
306
321
|
config;
|
|
307
322
|
_onDidReauthenticate = new Emitter();
|
|
@@ -1728,7 +1743,7 @@ var GitHubApi = class {
|
|
|
1728
1743
|
let dedupeKey;
|
|
1729
1744
|
if (dedupable) {
|
|
1730
1745
|
try {
|
|
1731
|
-
dedupeKey = `${token.microHash}|${provider?.id ?? ""}|${query}|${JSON.stringify(variables ?? null)}`;
|
|
1746
|
+
dedupeKey = `${token.microHash}|${provider?.id ?? ""}|${allowPartialNotFound ?? ""}|${query}|${JSON.stringify(variables ?? null)}`;
|
|
1732
1747
|
} catch {
|
|
1733
1748
|
dedupeKey = void 0;
|
|
1734
1749
|
}
|
|
@@ -1750,10 +1765,19 @@ var GitHubApi = class {
|
|
|
1750
1765
|
};
|
|
1751
1766
|
}
|
|
1752
1767
|
const retryable = graphqlReadQueryRegex.test(query);
|
|
1753
|
-
|
|
1768
|
+
const data = await this.requestWithRetries(() => this.config.wrapForForcedInsecureSSL(provider?.getIgnoreSSLErrors() ?? false, () => this.getDefaults(accessToken, graphql)(query, variables)), retryable, cancellation, scope);
|
|
1769
|
+
return allowPartialNotFound === "aliased" ? {
|
|
1770
|
+
data,
|
|
1771
|
+
errors: []
|
|
1772
|
+
} : data;
|
|
1754
1773
|
} catch (ex) {
|
|
1755
1774
|
if (ex instanceof GraphqlResponseError) {
|
|
1756
|
-
if (allowPartialNotFound && ex.data != null &&
|
|
1775
|
+
if (allowPartialNotFound === "aliased" && ex.data != null && ex.errors != null && ex.errors.length > 0) {
|
|
1776
|
+
if (ex.errors.every((e) => e.path != null && e.path.length > 0 && e.path[0] in ex.data)) return {
|
|
1777
|
+
data: ex.data,
|
|
1778
|
+
errors: ex.errors
|
|
1779
|
+
};
|
|
1780
|
+
}
|
|
1757
1781
|
switch (ex.errors?.[0]?.type) {
|
|
1758
1782
|
case "NOT_FOUND": throw new RequestNotFoundError(ex);
|
|
1759
1783
|
case "FORBIDDEN": throw new AuthenticationError(tokenInfo, 3, ex);
|
|
@@ -1768,7 +1792,7 @@ var GitHubApi = class {
|
|
|
1768
1792
|
}
|
|
1769
1793
|
}
|
|
1770
1794
|
if (_logger.isDebugging) this.config.onDebugError?.(`GitHub request failed: ${ex.errors?.[0]?.message ?? ex.message}`);
|
|
1771
|
-
} else if (ex instanceof RequestError || ex.name === "AbortError") this.handleRequestError(provider, token, ex, scope);
|
|
1795
|
+
} else if (ex instanceof RequestError || ex.name === "AbortError") this.handleRequestError(provider, token, ex, scope, allowPartialNotFound === "aliased");
|
|
1772
1796
|
else if (_logger.isDebugging) this.config.onDebugError?.(`GitHub request failed: ${ex.message}`);
|
|
1773
1797
|
throw ex;
|
|
1774
1798
|
}
|
|
@@ -1812,7 +1836,7 @@ var GitHubApi = class {
|
|
|
1812
1836
|
const retryable = method === "GET" || method === "HEAD";
|
|
1813
1837
|
return await this.requestWithRetries(() => this.config.wrapForForcedInsecureSSL(provider?.getIgnoreSSLErrors() ?? false, () => this.getDefaults(accessToken, request)(route, options)), retryable, signal, scope);
|
|
1814
1838
|
} catch (ex) {
|
|
1815
|
-
if (ex instanceof RequestError || ex.name === "AbortError") this.handleRequestError(provider, token, ex, scope);
|
|
1839
|
+
if (ex instanceof RequestError || ex.name === "AbortError") this.handleRequestError(provider, token, ex, scope, void 0);
|
|
1816
1840
|
else if (_logger.isDebugging) this.config.onDebugError?.(`GitHub request failed: ${ex.message}`);
|
|
1817
1841
|
throw ex;
|
|
1818
1842
|
}
|
|
@@ -1856,7 +1880,7 @@ var GitHubApi = class {
|
|
|
1856
1880
|
}
|
|
1857
1881
|
return defaults;
|
|
1858
1882
|
}
|
|
1859
|
-
handleRequestError(provider, token, ex, scope) {
|
|
1883
|
+
handleRequestError(provider, token, ex, scope, deferFailure) {
|
|
1860
1884
|
if (ex.name === "AbortError") throw new CancellationError(ex);
|
|
1861
1885
|
const { accessToken, ...tokenInfo } = token;
|
|
1862
1886
|
switch (ex.status) {
|
|
@@ -1870,23 +1894,18 @@ var GitHubApi = class {
|
|
|
1870
1894
|
throw new AuthenticationError(tokenInfo, 3, ex);
|
|
1871
1895
|
case 500:
|
|
1872
1896
|
scope?.error(ex);
|
|
1873
|
-
if (ex.response != null) {
|
|
1874
|
-
provider?.trackRequestException();
|
|
1875
|
-
this.config.onRequestError?.(provider, provider == null || provider.id === "github" ? l10n.t("{0} failed to respond and might be experiencing issues. Please visit the [GitHub status page](https://githubstatus.com) for more information.", provider?.name ?? "GitHub") : l10n.t("{0} failed to respond and might be experiencing issues.", provider.name));
|
|
1876
|
-
}
|
|
1897
|
+
if (ex.response != null) reportRequestFailure(provider, ex, () => this.config.onRequestError?.(provider, provider == null || provider.id === "github" ? l10n.t("{0} failed to respond and might be experiencing issues. Please visit the [GitHub status page](https://githubstatus.com) for more information.", provider?.name ?? "GitHub") : l10n.t("{0} failed to respond and might be experiencing issues.", provider.name)), deferFailure);
|
|
1877
1898
|
return;
|
|
1878
1899
|
case 502:
|
|
1879
1900
|
scope?.error(ex);
|
|
1880
1901
|
if (ex.message.includes("timeout")) {
|
|
1881
|
-
provider?.
|
|
1882
|
-
this.config.onRequestError?.(provider, `${provider?.name ?? "GitHub"} request timed out`);
|
|
1902
|
+
reportRequestFailure(provider, ex, () => this.config.onRequestError?.(provider, `${provider?.name ?? "GitHub"} request timed out`), deferFailure);
|
|
1883
1903
|
return;
|
|
1884
1904
|
}
|
|
1885
1905
|
break;
|
|
1886
1906
|
case 503:
|
|
1887
1907
|
scope?.error(ex);
|
|
1888
|
-
provider?.
|
|
1889
|
-
this.config.onRequestError?.(provider, provider == null || provider.id === "github" ? l10n.t("{0} failed to respond and might be experiencing issues. Please visit the [GitHub status page](https://githubstatus.com) for more information.", provider?.name ?? "GitHub") : l10n.t("{0} failed to respond and might be experiencing issues.", provider.name));
|
|
1908
|
+
reportRequestFailure(provider, ex, () => this.config.onRequestError?.(provider, provider == null || provider.id === "github" ? l10n.t("{0} failed to respond and might be experiencing issues. Please visit the [GitHub status page](https://githubstatus.com) for more information.", provider?.name ?? "GitHub") : l10n.t("{0} failed to respond and might be experiencing issues.", provider.name)), deferFailure);
|
|
1890
1909
|
return;
|
|
1891
1910
|
default: if (ex.status >= 400 && ex.status < 500) throw new RequestClientError(ex);
|
|
1892
1911
|
}
|
|
@@ -2206,8 +2225,10 @@ var GitHubApi = class {
|
|
|
2206
2225
|
*
|
|
2207
2226
|
* Returns POSITIONALLY — one slot per input coordinate, in order — for the same reason {@link countIssues}
|
|
2208
2227
|
* does: a caller's key is arbitrary text and would break the GraphQL document, so the aliases are generated
|
|
2209
|
-
* and the caller maps back by index. `
|
|
2210
|
-
* to this token)
|
|
2228
|
+
* and the caller maps back by index. A `fulfilled` slot with `undefined` means the issue does not exist (or
|
|
2229
|
+
* is not visible to this token) — a PROVEN ABSENCE. A `rejected` slot means only THAT target failed — e.g. an
|
|
2230
|
+
* org enforcing SAML SSO the token isn't authorized for — which is not proof the issue is gone, so it must
|
|
2231
|
+
* not be cached as absent. A whole-request failure (bad credentials, rate limit, no data at all) still throws.
|
|
2211
2232
|
*/
|
|
2212
2233
|
async getIssuesBatch(provider, token, coordinates, options, cancellation) {
|
|
2213
2234
|
const scope = getScopedLogger();
|
|
@@ -2232,16 +2253,200 @@ var GitHubApi = class {
|
|
|
2232
2253
|
variables[`k${i}`] = c.number;
|
|
2233
2254
|
});
|
|
2234
2255
|
try {
|
|
2235
|
-
const rsp = await this.graphql(provider, token, query, variables, scope, cancellation,
|
|
2236
|
-
if (rsp == null)
|
|
2256
|
+
const rsp = await this.graphql(provider, token, query, variables, scope, cancellation, "aliased");
|
|
2257
|
+
if (rsp?.data == null) throw new Error("GitHub returned no data for the issue batch");
|
|
2237
2258
|
return coordinates.map((c, i) => {
|
|
2238
|
-
const
|
|
2239
|
-
|
|
2259
|
+
const alias = `i${i}`;
|
|
2260
|
+
const node = rsp.data[alias]?.issue;
|
|
2261
|
+
const verdict = getAliasErrorVerdict(rsp.errors, alias, node);
|
|
2262
|
+
if (verdict === "absent") return {
|
|
2263
|
+
status: "fulfilled",
|
|
2264
|
+
value: void 0
|
|
2265
|
+
};
|
|
2266
|
+
if (verdict != null) return verdict;
|
|
2267
|
+
if (node == null) return {
|
|
2268
|
+
status: "fulfilled",
|
|
2269
|
+
value: void 0
|
|
2270
|
+
};
|
|
2240
2271
|
try {
|
|
2241
|
-
return
|
|
2272
|
+
return {
|
|
2273
|
+
status: "fulfilled",
|
|
2274
|
+
value: fromGitHubIssue(node, provider)
|
|
2275
|
+
};
|
|
2242
2276
|
} catch (ex) {
|
|
2243
|
-
scope?.warn(`
|
|
2244
|
-
return
|
|
2277
|
+
scope?.warn(`failed to map issue; ${c.owner}/${c.repo}#${c.number}, ex=${ex}`);
|
|
2278
|
+
return {
|
|
2279
|
+
status: "rejected",
|
|
2280
|
+
reason: ex
|
|
2281
|
+
};
|
|
2282
|
+
}
|
|
2283
|
+
});
|
|
2284
|
+
} catch (ex) {
|
|
2285
|
+
throw this.handleException(ex, provider, scope);
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
/**
|
|
2289
|
+
* Resolves several pull requests, in any state (open/closed/merged), BY COORDINATE — `(owner, repo, number)`
|
|
2290
|
+
* — in one request, via aliased `repository` fields rather than aliased searches. The pull-request twin of
|
|
2291
|
+
* {@link getIssuesBatch}; see that method for why aliasing the point read (exact number, no result ceiling,
|
|
2292
|
+
* a proven absence) is the design.
|
|
2293
|
+
*
|
|
2294
|
+
* Selects the FULL {@link gqlPullRequestFragment} — not the lite shape {@link getPullRequest} uses — so a
|
|
2295
|
+
* row from this read carries the same fields (reviews, review requests, checks, diff stats, assignees,
|
|
2296
|
+
* mergeable state) as {@link searchMyPullRequestsPage}'s account-wide rows.
|
|
2297
|
+
*
|
|
2298
|
+
* Returns POSITIONALLY — one slot per input coordinate, in order — for the same reason {@link getIssuesBatch}
|
|
2299
|
+
* does: a caller's key is arbitrary text and would break the GraphQL document, so the aliases are generated
|
|
2300
|
+
* and the caller maps back by index. A `fulfilled` slot with `undefined` means the pull request (or its
|
|
2301
|
+
* repository) does not exist or is not visible to this token — a PROVEN ABSENCE. A `rejected` slot means only
|
|
2302
|
+
* THAT target failed — e.g. an org enforcing SAML SSO the token isn't authorized for — which is not proof the
|
|
2303
|
+
* pull request is gone, so it must not be cached as absent. A whole-request failure still throws.
|
|
2304
|
+
*/
|
|
2305
|
+
async getPullRequestsBatch(provider, token, coordinates, options, cancellation) {
|
|
2306
|
+
const scope = getScopedLogger();
|
|
2307
|
+
if (coordinates.length === 0) return [];
|
|
2308
|
+
const query = `query getPullRequestsBatch(
|
|
2309
|
+
${coordinates.map((_, i) => `$o${i}: String!\n\t\t\t\t$n${i}: String!\n\t\t\t\t$k${i}: Int!`).join("\n ")}
|
|
2310
|
+
$avatarSize: Int
|
|
2311
|
+
) {
|
|
2312
|
+
${coordinates.map((_, i) => `p${i}: repository(owner: $o${i}, name: $n${i}) {
|
|
2313
|
+
pullRequest(number: $k${i}) {
|
|
2314
|
+
${gqlPullRequestFragment}
|
|
2315
|
+
${gqlPullRequestStackFragmentFor(options)}
|
|
2316
|
+
}
|
|
2317
|
+
}`).join("\n ")}
|
|
2318
|
+
}`;
|
|
2319
|
+
const variables = {
|
|
2320
|
+
baseUrl: options?.baseUrl,
|
|
2321
|
+
avatarSize: options?.avatarSize
|
|
2322
|
+
};
|
|
2323
|
+
coordinates.forEach((c, i) => {
|
|
2324
|
+
variables[`o${i}`] = c.owner;
|
|
2325
|
+
variables[`n${i}`] = c.repo;
|
|
2326
|
+
variables[`k${i}`] = c.number;
|
|
2327
|
+
});
|
|
2328
|
+
try {
|
|
2329
|
+
const rsp = await this.graphql(provider, token, query, variables, scope, cancellation, "aliased");
|
|
2330
|
+
if (rsp?.data == null) throw new Error("GitHub returned no data for the pull request batch");
|
|
2331
|
+
return coordinates.map((c, i) => {
|
|
2332
|
+
const alias = `p${i}`;
|
|
2333
|
+
const node = rsp.data[alias]?.pullRequest;
|
|
2334
|
+
const verdict = getAliasErrorVerdict(rsp.errors, alias, node);
|
|
2335
|
+
if (verdict === "absent") return {
|
|
2336
|
+
status: "fulfilled",
|
|
2337
|
+
value: void 0
|
|
2338
|
+
};
|
|
2339
|
+
if (verdict != null) return verdict;
|
|
2340
|
+
if (node == null) return {
|
|
2341
|
+
status: "fulfilled",
|
|
2342
|
+
value: void 0
|
|
2343
|
+
};
|
|
2344
|
+
try {
|
|
2345
|
+
return {
|
|
2346
|
+
status: "fulfilled",
|
|
2347
|
+
value: fromGitHubPullRequest(node, provider)
|
|
2348
|
+
};
|
|
2349
|
+
} catch (ex) {
|
|
2350
|
+
scope?.warn(`failed to map pull request; ${c.owner}/${c.repo}#${c.number}, ex=${ex}`);
|
|
2351
|
+
return {
|
|
2352
|
+
status: "rejected",
|
|
2353
|
+
reason: ex
|
|
2354
|
+
};
|
|
2355
|
+
}
|
|
2356
|
+
});
|
|
2357
|
+
} catch (ex) {
|
|
2358
|
+
throw this.handleException(ex, provider, scope);
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
/**
|
|
2362
|
+
* Finds, for several branches in one request, every pull request whose head is that branch — in any state,
|
|
2363
|
+
* most recently updated first, up to `limit` per branch. Each target names the BASE repository the pull
|
|
2364
|
+
* requests are opened against, the head branch's short name and, for a branch that lives in a fork,
|
|
2365
|
+
* `headOwner`, the fork's owner.
|
|
2366
|
+
*
|
|
2367
|
+
* Keyed on the head ref NAME (`repository.pullRequests(headRefName:)`) rather than on the ref itself
|
|
2368
|
+
* (`repository.ref(qualifiedName:).associatedPullRequests`, which {@link getPullRequestForBranch} uses): a
|
|
2369
|
+
* merged pull request's branch is usually deleted afterwards, and the ref lookup then answers "none" for a
|
|
2370
|
+
* pull request that exists.
|
|
2371
|
+
*
|
|
2372
|
+
* `headRefName` matches every fork's branch of that name too, so rows are kept only when their head
|
|
2373
|
+
* repository is the base repository itself (`headOwner` omitted) or a fork owned by `headOwner` — otherwise
|
|
2374
|
+
* a `main` in the base repository would claim every fork's `main`. That filter runs after the server's
|
|
2375
|
+
* `limit`, so `truncated` is set whenever the server matched more rows than it returned, since any of the
|
|
2376
|
+
* unfetched ones might have passed it.
|
|
2377
|
+
*
|
|
2378
|
+
* Returns POSITIONALLY, with the same per-alias rules as {@link getPullRequestsBatch}: a missing base
|
|
2379
|
+
* repository (NOT_FOUND on a null repository) is a PROVEN "none" — an empty list — while any other error on
|
|
2380
|
+
* a target's alias rejects only that target, and a whole-request failure still throws.
|
|
2381
|
+
*/
|
|
2382
|
+
async getPullRequestsForBranches(provider, token, targets, options, cancellation) {
|
|
2383
|
+
const scope = getScopedLogger();
|
|
2384
|
+
if (targets.length === 0) return [];
|
|
2385
|
+
const query = `query getPullRequestsForBranches(
|
|
2386
|
+
${targets.map((_, i) => `$o${i}: String!\n\t\t\t\t$n${i}: String!\n\t\t\t\t$h${i}: String!`).join("\n ")}
|
|
2387
|
+
$limit: Int!
|
|
2388
|
+
$avatarSize: Int
|
|
2389
|
+
) {
|
|
2390
|
+
${targets.map((_, i) => `b${i}: repository(owner: $o${i}, name: $n${i}) {
|
|
2391
|
+
pullRequests(headRefName: $h${i}, states: [OPEN, CLOSED, MERGED], first: $limit, orderBy: {field: UPDATED_AT, direction: DESC}) {
|
|
2392
|
+
totalCount
|
|
2393
|
+
nodes {
|
|
2394
|
+
${gqlPullRequestFragment}
|
|
2395
|
+
${gqlPullRequestStackFragmentFor(options)}
|
|
2396
|
+
headRepositoryOwner {
|
|
2397
|
+
login
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
}`).join("\n ")}
|
|
2402
|
+
}`;
|
|
2403
|
+
const variables = {
|
|
2404
|
+
baseUrl: options.baseUrl,
|
|
2405
|
+
avatarSize: options.avatarSize,
|
|
2406
|
+
limit: options.limit
|
|
2407
|
+
};
|
|
2408
|
+
targets.forEach((t, i) => {
|
|
2409
|
+
variables[`o${i}`] = t.owner;
|
|
2410
|
+
variables[`n${i}`] = t.repo;
|
|
2411
|
+
variables[`h${i}`] = t.branch;
|
|
2412
|
+
});
|
|
2413
|
+
try {
|
|
2414
|
+
const rsp = await this.graphql(provider, token, query, variables, scope, cancellation, "aliased");
|
|
2415
|
+
if (rsp?.data == null) throw new Error("GitHub returned no data for the pull requests by branch");
|
|
2416
|
+
return targets.map((t, i) => {
|
|
2417
|
+
const alias = `b${i}`;
|
|
2418
|
+
const repository = rsp.data[alias];
|
|
2419
|
+
const verdict = getAliasErrorVerdict(rsp.errors, alias, repository);
|
|
2420
|
+
if (verdict != null && verdict !== "absent") return verdict;
|
|
2421
|
+
if (repository == null) return {
|
|
2422
|
+
status: "fulfilled",
|
|
2423
|
+
value: {
|
|
2424
|
+
pullRequests: [],
|
|
2425
|
+
truncated: false
|
|
2426
|
+
}
|
|
2427
|
+
};
|
|
2428
|
+
const connection = repository.pullRequests;
|
|
2429
|
+
if (connection == null) return {
|
|
2430
|
+
status: "rejected",
|
|
2431
|
+
reason: /* @__PURE__ */ new Error(`GitHub returned no pull requests for ${t.owner}/${t.repo}:${t.branch}`)
|
|
2432
|
+
};
|
|
2433
|
+
const headOwner = t.headOwner?.toLowerCase();
|
|
2434
|
+
const nodes = connection.nodes.filter((pr) => pr != null);
|
|
2435
|
+
const matches = nodes.filter((pr) => pr.headRefName === t.branch && (headOwner == null ? !pr.isCrossRepository : pr.isCrossRepository && pr.headRepositoryOwner?.login.toLowerCase() === headOwner));
|
|
2436
|
+
try {
|
|
2437
|
+
return {
|
|
2438
|
+
status: "fulfilled",
|
|
2439
|
+
value: {
|
|
2440
|
+
pullRequests: matches.map((pr) => fromGitHubPullRequest(pr, provider)).sort((a, b) => b.updatedDate.getTime() - a.updatedDate.getTime()),
|
|
2441
|
+
truncated: connection.totalCount > nodes.length
|
|
2442
|
+
}
|
|
2443
|
+
};
|
|
2444
|
+
} catch (ex) {
|
|
2445
|
+
scope?.warn(`failed to map pull requests; ${t.owner}/${t.repo}:${t.branch}, ex=${ex}`);
|
|
2446
|
+
return {
|
|
2447
|
+
status: "rejected",
|
|
2448
|
+
reason: ex
|
|
2449
|
+
};
|
|
2245
2450
|
}
|
|
2246
2451
|
});
|
|
2247
2452
|
} catch (ex) {
|
|
@@ -3016,6 +3221,14 @@ __decorate([trace({ args: (provider, token) => ({
|
|
|
3016
3221
|
provider: provider.name,
|
|
3017
3222
|
token: `<token:${token.microHash}>`
|
|
3018
3223
|
}) })], GitHubApi.prototype, "getIssuesBatch", null);
|
|
3224
|
+
__decorate([trace({ args: (provider, token) => ({
|
|
3225
|
+
provider: provider.name,
|
|
3226
|
+
token: `<token:${token.microHash}>`
|
|
3227
|
+
}) })], GitHubApi.prototype, "getPullRequestsBatch", null);
|
|
3228
|
+
__decorate([trace({ args: (provider, token) => ({
|
|
3229
|
+
provider: provider.name,
|
|
3230
|
+
token: `<token:${token.microHash}>`
|
|
3231
|
+
}) })], GitHubApi.prototype, "getPullRequestsForBranches", null);
|
|
3019
3232
|
__decorate([trace({ args: (provider, token) => ({
|
|
3020
3233
|
provider: provider.name,
|
|
3021
3234
|
token: `<token:${token.microHash}>`
|