@gitkraken/core-gitlens 0.7.0 → 0.7.2
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 +28 -2
- package/dist/git/remotes/azure-devops.js +3 -3
- package/dist/git/remotes/azure-devops.js.map +1 -1
- package/dist/plus/integrations/authentication/configuredIntegrationService.js +9 -2
- package/dist/plus/integrations/authentication/configuredIntegrationService.js.map +1 -1
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js +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 +3 -3
- package/dist/plus/integrations/index.js.map +1 -1
- package/dist/plus/integrations/integrationService.d.ts +35 -1
- package/dist/plus/integrations/integrationService.js +90 -43
- package/dist/plus/integrations/integrationService.js.map +1 -1
- package/dist/plus/integrations/lite.js +5 -4
- package/dist/plus/integrations/lite.js.map +1 -1
- package/dist/plus/integrations/manager.d.ts +68 -23
- package/dist/plus/integrations/models/gitHostIntegration.d.ts +31 -15
- package/dist/plus/integrations/models/gitHostIntegration.js +71 -22
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
- package/dist/plus/integrations/models/integration.d.ts +70 -12
- package/dist/plus/integrations/models/integration.js +56 -1
- package/dist/plus/integrations/models/integration.js.map +1 -1
- package/dist/plus/integrations/models/issueReads.d.ts +17 -0
- package/dist/plus/integrations/models/issuesIntegration.js +2 -0
- package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
- package/dist/plus/integrations/models/pullRequestReads.d.ts +26 -0
- package/dist/plus/integrations/providers/azure/azure.d.ts +66 -1
- package/dist/plus/integrations/providers/azure/azure.js +192 -12
- package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
- package/dist/plus/integrations/providers/azure/search.d.ts +144 -0
- package/dist/plus/integrations/providers/azure/search.js +250 -0
- package/dist/plus/integrations/providers/azure/search.js.map +1 -0
- package/dist/plus/integrations/providers/azureDevOps.d.ts +73 -36
- package/dist/plus/integrations/providers/azureDevOps.js +191 -122
- package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOpsServer.d.ts +176 -0
- package/dist/plus/integrations/providers/azureDevOpsServer.js +560 -0
- package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server/discovery.d.ts +12 -0
- package/dist/plus/integrations/providers/bitbucket-server/discovery.js +128 -0
- package/dist/plus/integrations/providers/bitbucket-server/discovery.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server/models.d.ts +10 -1
- package/dist/plus/integrations/providers/bitbucket-server/models.js +3 -2
- package/dist/plus/integrations/providers/bitbucket-server/models.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.d.ts +58 -0
- package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js +485 -0
- package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server.d.ts +61 -3
- package/dist/plus/integrations/providers/bitbucket-server.js +114 -20
- package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket.d.ts +9 -1
- package/dist/plus/integrations/providers/bitbucket.js +13 -2
- package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
- package/dist/plus/integrations/providers/github.d.ts +6 -6
- package/dist/plus/integrations/providers/github.js +35 -34
- package/dist/plus/integrations/providers/github.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab.d.ts +6 -4
- package/dist/plus/integrations/providers/gitlab.js +32 -28
- package/dist/plus/integrations/providers/gitlab.js.map +1 -1
- package/dist/plus/integrations/providers/issueSorts.d.ts +1 -0
- package/dist/plus/integrations/providers/jira-server.d.ts +9 -0
- package/dist/plus/integrations/providers/jira-server.js +15 -7
- 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 +14 -2
- package/dist/plus/integrations/providers/jira.js.map +1 -1
- package/dist/plus/integrations/providers/linear.js +2 -2
- package/dist/plus/integrations/providers/models.d.ts +10 -1
- package/dist/plus/integrations/providers/models.js +86 -0
- package/dist/plus/integrations/providers/models.js.map +1 -1
- package/dist/plus/integrations/providers/providersApi.d.ts +10 -0
- package/dist/plus/integrations/providers/providersApi.js +18 -3
- package/dist/plus/integrations/providers/providersApi.js.map +1 -1
- package/dist/plus/integrations/providers/utils.d.ts +12 -1
- package/dist/plus/integrations/providers/utils.js +36 -6
- package/dist/plus/integrations/providers/utils.js.map +1 -1
- package/dist/plus/integrations/reads/broaden.js +6 -6
- package/dist/plus/integrations/reads/broaden.js.map +1 -1
- package/dist/plus/integrations/reads/context.d.ts +1 -1
- package/dist/plus/integrations/reads/counts.d.ts +18 -4
- package/dist/plus/integrations/reads/counts.js +66 -15
- package/dist/plus/integrations/reads/counts.js.map +1 -1
- package/dist/plus/integrations/reads/cursors.js +1 -1
- package/dist/plus/integrations/reads/drains.d.ts +2 -1
- package/dist/plus/integrations/reads/drains.js +1 -1
- package/dist/plus/integrations/reads/filters.d.ts +1 -1
- package/dist/plus/integrations/reads/filters.js +17 -12
- package/dist/plus/integrations/reads/filters.js.map +1 -1
- package/dist/plus/integrations/reads/hierarchy.js +2 -2
- package/dist/plus/integrations/reads/hierarchy.js.map +1 -1
- package/dist/plus/integrations/reads/hierarchy.utils.js +1 -1
- package/dist/plus/integrations/reads/issueBatch.js +1 -1
- package/dist/plus/integrations/reads/issueTracker.js +2 -2
- package/dist/plus/integrations/reads/issues.js +2 -2
- package/dist/plus/integrations/reads/paging.js +1 -1
- package/dist/plus/integrations/reads/resolveRepository.d.ts +12 -11
- package/dist/plus/integrations/reads/resolveRepository.js +110 -19
- package/dist/plus/integrations/reads/resolveRepository.js.map +1 -1
- package/dist/plus/integrations/reads/searchIssues.js +4 -2
- package/dist/plus/integrations/reads/searchIssues.js.map +1 -1
- package/dist/plus/integrations/reads/searchPullRequests.js +9 -3
- package/dist/plus/integrations/reads/searchPullRequests.js.map +1 -1
- package/dist/plus/integrations/reads/sweeps.js +1 -1
- package/dist/plus/integrations/reads/trackerIssue.d.ts +9 -5
- package/dist/plus/integrations/reads/trackerIssue.js +15 -9
- package/dist/plus/integrations/reads/trackerIssue.js.map +1 -1
- package/dist/plus/integrations/reads/warnings.d.ts +6 -2
- package/dist/plus/integrations/reads/warnings.js +15 -19
- package/dist/plus/integrations/reads/warnings.js.map +1 -1
- package/dist/plus/integrations/results.d.ts +84 -6
- package/dist/plus/integrations/results.js +9 -2
- package/dist/plus/integrations/results.js.map +1 -1
- package/dist/plus/integrations/utils/domain.utils.d.ts +19 -0
- package/dist/plus/integrations/utils/domain.utils.js +36 -1
- package/dist/plus/integrations/utils/domain.utils.js.map +1 -1
- package/dist/plus/integrations/utils/integration.utils.d.ts +1 -0
- package/dist/plus/integrations/utils/integration.utils.js +12 -1
- package/dist/plus/integrations/utils/integration.utils.js.map +1 -1
- package/docs/integrations.md +263 -74
- package/docs/kepler-read-api-parity.md +19 -6
- package/package.json +1 -1
package/docs/integrations.md
CHANGED
|
@@ -113,39 +113,42 @@ provider before calling the token backend; never reuse an id discovered under a
|
|
|
113
113
|
Every read returns `ProviderResult<T>` (`items` + `warnings` + `fetchFailed?`), and every paged read extends
|
|
114
114
|
it with `page` + `hasMore` + `cursor?`. **No read throws for a provider-side failure** — see §6.
|
|
115
115
|
|
|
116
|
-
| Method | Returns | Scope
|
|
117
|
-
| ---------------------------- | ------------------------- |
|
|
118
|
-
| `listOrgs` | `ProviderOrganization` | Orgs / workspaces / groups; issue-tracker resources (Jira sites, …). |
|
|
119
|
-
| `listProjects` | `ProviderOrganization` | The project tier: Azure DevOps, and issue-tracker projects.
|
|
120
|
-
| `listRepos` | `ProviderRepositoryShape` | Repos of an `org`, or account-wide user-affiliated repos when `org` is omitted.
|
|
121
|
-
| `listPullRequestsPage` | `PullRequestShape` | With `repos`: those repos' PRs. Without: the user's PRs account-wide.
|
|
122
|
-
| `searchPullRequestsPage` | `PullRequestShape` | PRs involving the user that match structured criteria, optionally repo/org-scoped.
|
|
123
|
-
| `countPullRequests` | `PullRequestCountResult` | How many PRs match each scope, fetching none
|
|
124
|
-
| `listIssuesPage` | `IssueShape` | Same split, for a **git host**'s issues.
|
|
125
|
-
| `searchIssuesPage` | `IssueShape` | Issues matching structured criteria over a repo/org scope — **no** `@me` binding.
|
|
126
|
-
| `countIssues` | `IssueCountResult` | How many match each scope, fetching none of them. See §5.1.
|
|
127
|
-
| `getIssuesBatch` | `IssueBatchResult` | Resolves N `(owner, repo, number)` coordinates in one request; an absence is proven.
|
|
128
|
-
| `getTrackerIssue` | `TrackerIssueResult` | Resolves ONE tracker issue by key within a resource; an absence is proven. Jira/Linear. |
|
|
129
|
-
| `listIssueTrackerIssuesPage` | `IssueShape` | Jira (Cloud + Data Center) / Linear / Trello (issues live under resource → project).
|
|
130
|
-
| `sweepPullRequests` | `ProviderSweepResult` | Drains **every** page across providers (`maxPages`, default 100).
|
|
131
|
-
| `sweepClosedPullRequests` | `ProviderSweepResult` | Same, pinned to `['closed','merged']`.
|
|
132
|
-
| `broadenIssues` | `ProviderBroadenResult` | Per-org fan-out for every visible issue, unfiltered by assignee.
|
|
133
|
-
| `resolveRepository` | `ResolveRepositoryResult` | Remote URL → canonical provider identity (the `gk repo resolve` equivalent).
|
|
134
|
-
| `getSupportedFilters` | filter capability table | Static, connection-free. See §7.
|
|
116
|
+
| Method | Returns | Scope |
|
|
117
|
+
| ---------------------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
118
|
+
| `listOrgs` | `ProviderOrganization` | Orgs / workspaces / groups / Bitbucket DC projects; issue-tracker resources (Jira sites, …). |
|
|
119
|
+
| `listProjects` | `ProviderOrganization` | The project tier: Azure DevOps, and issue-tracker projects. |
|
|
120
|
+
| `listRepos` | `ProviderRepositoryShape` | Repos of an `org`, or account-wide user-affiliated repos when `org` is omitted. |
|
|
121
|
+
| `listPullRequestsPage` | `PullRequestShape` | With `repos`: those repos' PRs. Without: the user's PRs account-wide. |
|
|
122
|
+
| `searchPullRequestsPage` | `PullRequestShape` | PRs involving the user that match structured criteria, optionally repo/org-scoped. |
|
|
123
|
+
| `countPullRequests` | `PullRequestCountResult` | How many PRs match each scope, fetching none where the provider can count. See §5.1. |
|
|
124
|
+
| `listIssuesPage` | `IssueShape` | Same split, for a **git host**'s issues. |
|
|
125
|
+
| `searchIssuesPage` | `IssueShape` | Issues matching structured criteria over a repo/org scope — **no** `@me` binding. |
|
|
126
|
+
| `countIssues` | `IssueCountResult` | How many match each scope, fetching none of them. See §5.1. |
|
|
127
|
+
| `getIssuesBatch` | `IssueBatchResult` | Resolves N `(owner, repo, number)` coordinates in one request; an absence is proven. |
|
|
128
|
+
| `getTrackerIssue` | `TrackerIssueResult` | Resolves ONE tracker issue by key within a resource; an absence is proven. Jira (Cloud + Data Center) / Linear. |
|
|
129
|
+
| `listIssueTrackerIssuesPage` | `IssueShape` | Jira (Cloud + Data Center) / Linear / Trello (issues live under resource → project). |
|
|
130
|
+
| `sweepPullRequests` | `ProviderSweepResult` | Drains **every** page across providers (`maxPages`, default 100). |
|
|
131
|
+
| `sweepClosedPullRequests` | `ProviderSweepResult` | Same, pinned to `['closed','merged']`. |
|
|
132
|
+
| `broadenIssues` | `ProviderBroadenResult` | Per-org fan-out for every visible issue, unfiltered by assignee. |
|
|
133
|
+
| `resolveRepository` | `ResolveRepositoryResult` | Remote URL → canonical provider identity (the `gk repo resolve` equivalent). |
|
|
134
|
+
| `getSupportedFilters` | filter capability table | Static, connection-free. See §7. |
|
|
135
135
|
|
|
136
136
|
A provider that cannot serve a surface says so explicitly — a warning explaining that the operation is
|
|
137
137
|
unsupported plus `fetchFailed`, never a silent empty page. That distinction is the whole point of the result
|
|
138
138
|
shape: an empty `items` with no warning means "this account genuinely has nothing".
|
|
139
139
|
|
|
140
|
-
`getTrackerIssue` takes `resourceId` for
|
|
140
|
+
`getTrackerIssue` takes `resourceId` for every supported tracker. Jira Cloud also takes `resourceUrl`, the site URL
|
|
141
141
|
returned by `listOrgs`; the REST response only supplies an API `self` link, so the caller provides the already-known
|
|
142
|
-
site identity rather than making this point read perform resource discovery. Linear does not need it
|
|
142
|
+
site identity rather than making this point read perform resource discovery. Linear does not need it, and neither
|
|
143
|
+
does Jira Data Center, whose browser link is built from the connection's own base URL.
|
|
143
144
|
|
|
144
|
-
`
|
|
145
|
-
|
|
146
|
-
self-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
For Jira Data Center `resourceId` is the host — the instance's single resource, as `listOrgs` reports it — and the
|
|
146
|
+
read takes the `domain` its siblings take to select the instance. Unlike them it never falls back to the primary
|
|
147
|
+
connection: a self-managed tracker requires a `domain` or a `connectionId` with a configured host, and is refused
|
|
148
|
+
(warning + `fetchFailed`) otherwise. Two self-hosted instances routinely share project and issue keys, and this
|
|
149
|
+
read's `issue: undefined` is a proven absence a caller may cache, so an answer from whichever host happens to be
|
|
150
|
+
primary would be cached under a key that names a different instance. For the same reason a `resourceId` that names
|
|
151
|
+
a different host than the one the read resolves to is refused rather than read.
|
|
149
152
|
|
|
150
153
|
## 5. Paging
|
|
151
154
|
|
|
@@ -214,9 +217,11 @@ Omit `relationships` to search every PR in the supplied repo/org scope; without
|
|
|
214
217
|
relationship is mandatory. This is deliberately not `involves:@me`: that GitHub shortcut excludes
|
|
215
218
|
`review-requested` but includes `commenter`, so it cannot match the adjacent visible-PR list.
|
|
216
219
|
|
|
217
|
-
The
|
|
218
|
-
|
|
219
|
-
|
|
220
|
+
The read is ordered by `criteria.sort`, most-recently-updated-first when omitted; the keys a provider accepts are
|
|
221
|
+
`getSupportedFilters().pullRequestSearch.sorts`. On GitHub/GHE a threaded `cursor` is exactly one upstream request,
|
|
222
|
+
since every active relationship × state facet travels as an alias in one GraphQL document; Bitbucket Data Center
|
|
223
|
+
has no such batching and spends one request per repository × relationship facet still being read. A page number
|
|
224
|
+
without a cursor walks from page 1. At GitHub's 1,000-result-per-facet ceiling, `page.truncated` is true and
|
|
220
225
|
the warning's `omission` carries `totalCount`, `limit`, and `recovery: 'none'`. `totalCount` is the largest
|
|
221
226
|
provider-reported pre-ceiling facet count, matching the per-search ceiling's unit; it is not the returned or
|
|
222
227
|
still-reachable row count. Free text is sanitized so qualifier-shaped tokens such as `org:other` are removed
|
|
@@ -328,11 +333,23 @@ const counts = await manager.countPullRequests({
|
|
|
328
333
|
});
|
|
329
334
|
```
|
|
330
335
|
|
|
331
|
-
The one difference is inherent to pull requests: a scope's `states` (open/closed/merged) are
|
|
332
|
-
independent searches, so the reported `count` is the **largest** of them — the same total
|
|
336
|
+
The one difference is inherent to pull requests: on GitHub/GHE a scope's `states` (open/closed/merged) are
|
|
337
|
+
counted as independent searches, so the reported `count` is the **largest** of them — the same total
|
|
333
338
|
`searchPullRequestsPage` surfaces — not their sum. Because the result ceiling applies per search, that max is
|
|
334
339
|
what `exceedsProviderLimit` compares against. Several states in one scope are therefore fine (they are
|
|
335
|
-
disjoint); only several relationships are refused.
|
|
340
|
+
disjoint); only several relationships are refused, except on Bitbucket Data Center (below). Azure DevOps Server
|
|
341
|
+
reads every state in one drain, so its count is their union (the sum, since states are disjoint), again the total
|
|
342
|
+
its search pages through.
|
|
343
|
+
|
|
344
|
+
Bitbucket Data Center has no count query, no total on its pages and no result ceiling, so it counts by reading
|
|
345
|
+
each facet's first page of up to 1,000 pull requests through the same predicates the search applies. Its `count`
|
|
346
|
+
is therefore the exact **union** of the requested states — the number of rows the search returns — and when a
|
|
347
|
+
facet has more than one page it comes back with `lowerBound: true`: a floor, to be shown as "N+" and treated as
|
|
348
|
+
at least that expensive. Absent `lowerBound` means the count is exact, though computed from the rows read rather
|
|
349
|
+
than reported by the server. Because it reads the
|
|
350
|
+
rows, it also counts several relationships in one scope as their exact union, the same OR the search applies, so
|
|
351
|
+
the one-relationship-per-scope refusal does not apply there. Each scope is its own set of requests, so a Bitbucket
|
|
352
|
+
Data Center count is not free the way a GitHub one is; debounce and cache it.
|
|
336
353
|
|
|
337
354
|
## 6. Failures: warnings, `fetchFailed`, `truncated`
|
|
338
355
|
|
|
@@ -344,7 +361,7 @@ prove from structured errors:
|
|
|
344
361
|
|
|
345
362
|
| `kind` | Meaning | Reasonable response |
|
|
346
363
|
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
|
|
347
|
-
| `auth` | Token rejected (401/403 that isn't a throttle). | Prompt to reconnect that connection.
|
|
364
|
+
| `auth` | Token rejected (401/403 that isn't a throttle). | Prompt to reconnect that connection. A scoped one is narrower: see `scope` below. |
|
|
348
365
|
| `rate-limit` | Throttled (429, or a 403 whose body says so). | Back off and retry; keep the last snapshot. |
|
|
349
366
|
| `not-found` | 404/410/422 on the requested scope. | Drop that scope; don't reconnect. |
|
|
350
367
|
| `no-connection` | The requested `connectionId`/`domain` doesn't resolve. | Re-resolve the target or re-authenticate. |
|
|
@@ -356,6 +373,92 @@ Conversely, `other` is intentionally not a complete failure taxonomy. Treat `mes
|
|
|
356
373
|
text rather than a stable protocol; use `fetchFailed`, `page.truncated`, and `page.allPages` for completeness
|
|
357
374
|
and keep unknown failures conservative.
|
|
358
375
|
|
|
376
|
+
### `scope` — which part of the read failed
|
|
377
|
+
|
|
378
|
+
A fan-out read records a failure against the organization, project or repository it happened in.
|
|
379
|
+
`ProviderWarning.scope` forwards that attribution (`resourceId`, `projectId`, `repositoryId`, whichever the
|
|
380
|
+
provider reported), so a consumer can tell "one organization refused this token" from "the connection's token
|
|
381
|
+
is dead" without parsing `message`:
|
|
382
|
+
|
|
383
|
+
```ts
|
|
384
|
+
if (warning.kind === 'auth' && warning.scope == null) {
|
|
385
|
+
promptToReconnect(warning.providerId, warning.connectionId);
|
|
386
|
+
} else if (warning.kind === 'auth') {
|
|
387
|
+
// One organization/project/repository refused the credential, e.g. an Azure DevOps organization with
|
|
388
|
+
// third-party OAuth access disabled, one in another Entra tenant, or a Conditional Access policy.
|
|
389
|
+
// Reconnecting cannot fix that, so mark only that scope unavailable and keep the others.
|
|
390
|
+
markScopeUnavailable(warning.providerId, warning.connectionId, warning.scope);
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
`kind` and `isAuth` do not change with it: a scoped 401 is still an authentication failure, and `scope` says
|
|
395
|
+
how far it reaches. **Its absence means account-wide or unattributed**, so a consumer that ignores the field
|
|
396
|
+
keeps its existing behavior. It is set only on warnings derived from a structured scope failure, and names at
|
|
397
|
+
least one ID when present; a failure attributed to nothing below the provider carries none. A warning built
|
|
398
|
+
from a caught exception never carries one, even when that call targeted a single organization, and an omission
|
|
399
|
+
keeps its attribution in `omission.scope` instead.
|
|
400
|
+
|
|
401
|
+
A scoped `auth` failure also means **the credential itself was accepted**. A dead token can come back as
|
|
402
|
+
nothing but scoped refusals wherever a read reaches its scopes without an uncached request to the connection
|
|
403
|
+
first: discovery served from a per-token cache (Azure DevOps, Bitbucket and Jira Cloud cache the account, its
|
|
404
|
+
organizations, workspaces or sites, and their projects), or an SDK fan-out across the requested repositories
|
|
405
|
+
(Bitbucket Data Center). So when a read's only auth failures are scoped, those providers confirm the credential
|
|
406
|
+
with one uncached check before reporting them. A refused credential fails the whole read instead: an
|
|
407
|
+
unscoped `auth` warning, `fetchFailed`, no results served from the cache, and the usual connection recovery.
|
|
408
|
+
A refusal the provider pins on the credential itself, like Bitbucket's or Jira Cloud's for a token missing the
|
|
409
|
+
OAuth scopes the read needs, is published unscoped too, once for the connection, because a reconnect
|
|
410
|
+
(consenting to them again) is what fixes it; the scopes that answered keep their results.
|
|
411
|
+
|
|
412
|
+
The promise holds for a read that carries no unscoped `auth` warning of its own: one that does already asks for a
|
|
413
|
+
reconnect, and its other scoped refusals are not checked. Two cases stay scoped even then. A check that could not
|
|
414
|
+
complete or was denied (a network error, a throttle, a `403`, Bitbucket Data Center refusing a credential it
|
|
415
|
+
authenticated, or a Bitbucket Data Center project access token, whose user the check cannot find) proves nothing,
|
|
416
|
+
so the warnings are published unconfirmed and carry no `cause`, and the next read checks again: a credential the
|
|
417
|
+
check can never confirm, like a project access token, costs one check on every read that has scoped refusals. And a
|
|
418
|
+
credential confirmed within the last minute is not checked again, so a scope that keeps refusing it costs at most
|
|
419
|
+
one extra check a minute, and a revocation can take up to a minute to surface as a connection failure.
|
|
420
|
+
|
|
421
|
+
`scope.resourceId` is the resource as the read addressed it: its id on most reads, its name on the few that
|
|
422
|
+
address it by name (Azure DevOps' repo-scoped reads, Bitbucket's workspace reads). Match it against both
|
|
423
|
+
`ProviderOrganization.id` and `name`.
|
|
424
|
+
|
|
425
|
+
Warnings also dedup on `scope` and `cause`, so failures of two scopes stay two warnings.
|
|
426
|
+
|
|
427
|
+
### `cause` — why a sound credential was refused
|
|
428
|
+
|
|
429
|
+
A scoped `auth` warning can also say **why** the scope refused, so a consumer recommends the fix instead of a
|
|
430
|
+
reconnect. `ProviderWarning.cause` carries a closed `reason` to switch on (also exported as
|
|
431
|
+
`ProviderWarningCauseReason`), the provider's own `code` when it reports one, and a `remedyUrl` when this layer
|
|
432
|
+
can address the setting behind the refusal. `message` says the same in prose.
|
|
433
|
+
|
|
434
|
+
```ts
|
|
435
|
+
switch (warning.cause?.reason) {
|
|
436
|
+
case 'oauth-app-not-allowed':
|
|
437
|
+
// An admin enables the org's third-party OAuth policy at `remedyUrl`, or the user connects with a PAT.
|
|
438
|
+
suggestAllowingOAuthApps(warning.scope, warning.cause.remedyUrl);
|
|
439
|
+
break;
|
|
440
|
+
case 'access-denied':
|
|
441
|
+
suggestRequestingAccess(warning.scope);
|
|
442
|
+
break;
|
|
443
|
+
case 'conditional-access':
|
|
444
|
+
suggestAskingTheTenantAdmin(warning.scope);
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
| `cause.reason` | Means | Fixed by |
|
|
450
|
+
| ----------------------- | ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
451
|
+
| `oauth-app-not-allowed` | The organization does not let third-party OAuth apps in. | An organization admin enabling **Third-party application access via OAuth** (Azure DevOps; off by default for new organizations), or a PAT, which the policy does not govern. |
|
|
452
|
+
| `access-denied` | The account has no access to that organization or project (not a member, no permission). | Someone who administers it granting access. |
|
|
453
|
+
| `conditional-access` | A Microsoft Entra Conditional Access policy blocked the request (`VS403463`). | The tenant admin exempting the request. |
|
|
454
|
+
|
|
455
|
+
It is set **only on a scoped `auth` warning whose credential was confirmed** (see `scope` above), because until
|
|
456
|
+
then these refusals look exactly like a dead credential: Azure DevOps answers a third-party OAuth app its
|
|
457
|
+
organization disallows with the same bare `401` it gives an expired token. Only Azure DevOps names causes today,
|
|
458
|
+
from answers captured against the live service. **Its absence proves nothing**: a refusal this layer cannot name
|
|
459
|
+
still carries the provider's own explanation, when it gave one, in `message`, e.g. an organization that only
|
|
460
|
+
allowlists global personal access tokens.
|
|
461
|
+
|
|
359
462
|
### `omission` — succeeded, but withheld results
|
|
360
463
|
|
|
361
464
|
`other` covers two facts with **opposite remedies**: a request that failed, and a request that succeeded while
|
|
@@ -539,7 +642,7 @@ read, and GitHub's carries `latestReviews` natively; account-wide (no `repos`) i
|
|
|
539
642
|
no option opts it back in. `commitOid` is absent from both: only the full projection populates it.
|
|
540
643
|
|
|
541
644
|
The paginated read that does carry the full projection is `searchPullRequestsPage` with
|
|
542
|
-
`criteria.relationships`
|
|
645
|
+
`criteria.relationships` on GitHub/GHE (Bitbucket Data Center also exposes the search, with its native row shape):
|
|
543
646
|
its results always include the review projection with `commitOid`, it honors `itemsPerPage`, and one threaded
|
|
544
647
|
cursor page is exactly one upstream request — every relationship × state facet travels in the same query,
|
|
545
648
|
unlike the account-wide read, which spends one request per facet per page. So a surface that pages
|
|
@@ -551,31 +654,40 @@ reach for `includeReviews`, which only exists on the all-at-once sweep.
|
|
|
551
654
|
Derived from the provider models and `providersMetadata`. ✓ supported · ✗ reported unsupported
|
|
552
655
|
(warning + `fetchFailed`) · — not applicable. Self-managed variants inherit their cloud family's hooks.
|
|
553
656
|
|
|
554
|
-
| Surface | GitHub / GHE | GitLab / self-hosted | Bitbucket | Bitbucket DC | Azure DevOps (+ Server) |
|
|
555
|
-
| ---------------------------- | :----------: | :------------------: | :-------: | :----------: | :---------------------: |
|
|
556
|
-
| `listOrgs` | ✓ | ✓ | ✓ |
|
|
557
|
-
| `listProjects` | — | — | — | — | ✓ |
|
|
558
|
-
| `listRepos` (`org`) | ✓ | ✓ | ✓ |
|
|
559
|
-
| `listRepos` (account-wide) | ✓ | ✓ | ✗ |
|
|
560
|
-
| PRs, repo-scoped | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
561
|
-
| PRs, account-wide | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
562
|
-
| PR `states` account-wide | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
563
|
-
| `searchPullRequestsPage` | ✓ | ✗ | ✗ |
|
|
564
|
-
| `countPullRequests` | ✓ | ✗ | ✗ |
|
|
565
|
-
| Issues, repo-scoped | ✓ | ✓ | ✗ | ✗ | ✓ |
|
|
566
|
-
| Issues, account-wide | ✓ | ✓ | ✗ | ✗ | ✓ |
|
|
567
|
-
| `searchIssuesPage` | ✓ | ✓ | ✗ | ✗ | ✗ |
|
|
568
|
-
| `countIssues` | ✓ | ✓ | ✗ | ✗ | ✗ |
|
|
569
|
-
| `getIssuesBatch` | ✓ | ✓ | ✗ | ✗ | ✗ |
|
|
570
|
-
| `getTrackerIssue` | ✗ | ✗ | ✗ | ✗ | ✗ |
|
|
571
|
-
| Issues by `org`/`project` | ✗ | ✗ | ✗ | ✗ | ✓ |
|
|
572
|
-
| `listIssueTrackerIssuesPage` | — | — | — | — | — |
|
|
573
|
-
| `broadenIssues` | ✓ | ✓ | ✗ | ✗ | ✓ |
|
|
574
|
-
| `resolveRepository` | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
657
|
+
| Surface | GitHub / GHE | GitLab / self-hosted | Bitbucket | Bitbucket DC | Azure DevOps (+ Server) | Jira (+ DC) | Linear | Trello |
|
|
658
|
+
| ---------------------------- | :----------: | :------------------: | :-------: | :----------: | :---------------------: | :---------: | :----: | :----: |
|
|
659
|
+
| `listOrgs` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
660
|
+
| `listProjects` | — | — | — | — | ✓ | ✓ | ✓ | ✓ |
|
|
661
|
+
| `listRepos` (`org`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
|
|
662
|
+
| `listRepos` (account-wide) | ✓ | ✓ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ |
|
|
663
|
+
| PRs, repo-scoped | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
|
|
664
|
+
| PRs, account-wide | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
|
|
665
|
+
| PR `states` account-wide | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — |
|
|
666
|
+
| `searchPullRequestsPage` | ✓ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ |
|
|
667
|
+
| `countPullRequests` | ✓ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ |
|
|
668
|
+
| Issues, repo-scoped | ✓ | ✓ | ✗ | ✗ | ✓ | — | — | — |
|
|
669
|
+
| Issues, account-wide | ✓ | ✓ | ✗ | ✗ | ✓ | — | — | — |
|
|
670
|
+
| `searchIssuesPage` | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
|
|
671
|
+
| `countIssues` | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
|
|
672
|
+
| `getIssuesBatch` | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
|
|
673
|
+
| `getTrackerIssue` | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✓ | ✗ |
|
|
674
|
+
| Issues by `org`/`project` | ✗ | ✗ | ✗ | ✗ | ✓ | ✓ | ✓ | ✓ |
|
|
675
|
+
| `listIssueTrackerIssuesPage` | — | — | — | — | — | ✓ | ✓ | ✓ |
|
|
676
|
+
| `broadenIssues` | ✓ | ✓ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ |
|
|
677
|
+
| `resolveRepository` | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
|
|
678
|
+
|
|
679
|
+
Bitbucket Data Center exposes its projects through `listOrgs`: both `id` and `name` are the project key.
|
|
680
|
+
Pass that key as `org` to `listRepos` to select a project, or omit `org` to enumerate all accessible repositories,
|
|
681
|
+
including personal repositories. It has no additional project tier, so `listProjects` is not applicable.
|
|
682
|
+
Project discovery drains up to 20 pages and reports `fetchFailed` with warnings if incomplete. Repository
|
|
683
|
+
discovery returns one page with an opaque continuation cursor; reuse it with the same connection and `org`.
|
|
684
|
+
Both reads deduplicate results across pages and retain the configured installation URL, including its context path.
|
|
685
|
+
A link the server returns is kept only when it names that entry on the configured installation; otherwise the web and
|
|
686
|
+
HTTPS links are rebuilt from the configured URL and an SSH link, whose host and port cannot be derived, is omitted.
|
|
687
|
+
|
|
688
|
+
Jira Data Center inherits Jira Cloud's row. Its reads are addressed per host, so `domain` selects the instance and
|
|
689
|
+
every read below is scoped to that one connection; a paged read that omits it gets the primary configured host,
|
|
690
|
+
while `getTrackerIssue` refuses instead (see §4). `listOrgs` returns exactly one resource — the
|
|
579
691
|
instance itself, synthesized from the configured host rather than fetched — and its projects carry the display name
|
|
580
692
|
as `key`, because `/rest/api/2/project` reports no project key; reads address the project by id regardless. No
|
|
581
693
|
autolinks are registered for the same reason: an autolink prefix has to be the project key.
|
|
@@ -590,8 +702,16 @@ exposes a reviewed-by axis on the repo-scoped read, so it is absent from the rep
|
|
|
590
702
|
PR **search** capabilities (`getSupportedFilters().pullRequestSearch`): GitHub/GHE express relationships
|
|
591
703
|
`Author, Assignee, ReviewRequested, Reviewed, Mention`, states `open, closed, merged, all`, `text`, `updatedAfter`,
|
|
592
704
|
`createdAfter`, `includeArchived`, `draft`, repository/organization scopes, and sorts
|
|
593
|
-
`updated:desc|asc, created:desc|asc`.
|
|
594
|
-
|
|
705
|
+
`updated:desc|asc, created:desc|asc`. Bitbucket Data Center expresses relationships `Author, ReviewRequested,
|
|
706
|
+
Reviewed`, states `open, closed, merged, all`, `text` (title or description), `includeArchived`, `draft`, the
|
|
707
|
+
repository scope, and sorts `updated:desc|asc` — no assignee or mention (its pull requests have neither), no date
|
|
708
|
+
filters, no `created` order, and no organization scope, since it has no project-wide pull-request list. Azure DevOps
|
|
709
|
+
Server expresses relationships `Author, Assignee, ReviewRequested` (the last two both read Azure's reviewers, since
|
|
710
|
+
it has no separate assignee), the same four states, `text` (title or description), `updatedAfter`, `createdAfter`,
|
|
711
|
+
`draft`, repository/organization scopes and `updated:desc|asc, created:desc|asc`; not `Reviewed`, `Mention` or
|
|
712
|
+
`includeArchived`. Every other provider — including Azure DevOps Services — declares empty lists and false flags,
|
|
713
|
+
so the read is refused rather than returning a page that did not
|
|
714
|
+
apply a requested criterion or scope. `updatedAfter` /
|
|
595
715
|
`createdAfter` are ISO `YYYY-MM-DD` and are the most effective narrowing on a large scope — the way to bound a broad
|
|
596
716
|
closed-PR read, rather than capping page iterations. `draft` is tri-state: `true` returns only drafts, `false` only
|
|
597
717
|
ready-for-review PRs, and omitting it places no constraint — so a consumer sending `draft: false` must not treat it
|
|
@@ -604,11 +724,13 @@ Account-wide issue filters: GitHub/GHE `Author, Assignee, Mention` · Azure `Aut
|
|
|
604
724
|
`Assignee, Author` · everything else none.
|
|
605
725
|
Issue **search** criteria (`getSupportedFilters().issueSearch`): GitHub/GHE express all of them —
|
|
606
726
|
relationships `authored, assigned, mentioned, any-assignee, unassigned`, plus `text`, `labels`, `milestone`,
|
|
607
|
-
`updatedAfter`, `createdAfter`, `withoutLinkedPullRequest`, `state
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
727
|
+
`updatedAfter`, `createdAfter`, `withoutLinkedPullRequest`, `state`. Azure DevOps Server expresses relationships
|
|
728
|
+
`authored, assigned, any-assignee, unassigned`, `text` (a title substring), `labels` (whole tags), `updatedAfter`,
|
|
729
|
+
`createdAfter` and `state`, and sorts `updated`, `created`, `closed`, `comments` and `title` in both directions —
|
|
730
|
+
not `mentioned` (`@RecentMentions` only reaches back 30 days), `milestone` or `withoutLinkedPullRequest`, and not
|
|
731
|
+
`priority`/`resolved`, whose process-template fields an on-premises collection may not define. Every other provider
|
|
732
|
+
declares none, so the read is refused there rather than serving a list that was never narrowed. GitLab and Azure
|
|
733
|
+
DevOps Services could express most of it, so the gap is unimplemented rather than impossible.
|
|
612
734
|
|
|
613
735
|
> `supportedCloudIntegrationDescriptors.supports` (in `constants.ts`) describes what GitLens _advertises in
|
|
614
736
|
> its connect UI_, including enrichment-only capabilities. It is **not** the read-capability answer — use
|
|
@@ -699,14 +821,71 @@ Markdown by this package.
|
|
|
699
821
|
repo walk (list per workspace). The account-wide PR read drains every workspace and returns **one
|
|
700
822
|
aggregate page** (no cross-workspace cursor), so `itemsPerPage` doesn't apply. The review-requested slice
|
|
701
823
|
is opt-in via `includeReviewRequested: true`, because it costs an O(workspaces × repos) fan-out.
|
|
702
|
-
- **Bitbucket Data Center** —
|
|
703
|
-
|
|
704
|
-
the
|
|
824
|
+
- **Bitbucket Data Center** — projects are the org tier; repositories can be listed by project or account-wide.
|
|
825
|
+
Discovery follows exact `nextPageStart` offsets, with cursors bound to the connection and scope. It has no
|
|
826
|
+
issues. Pull-request reads use the SDK's 1-based page numbers, carried inside their own opaque cursors.
|
|
827
|
+
The filtered PR search reads each requested repository × relationship as its own request (a relationship
|
|
828
|
+
without repositories reads the user's dashboard; `Reviewed` there is two requests, the reviewer and the
|
|
829
|
+
participant lists, because the dashboard only filters by review status together with a role), follows each
|
|
830
|
+
facet's own `nextPageStart`, and binds its
|
|
831
|
+
cursor to the connection, the configured installation URL and the query. Every criterion is re-checked on the
|
|
832
|
+
rows returned, so a server that ignores one (`draft` before 8.18) narrows instead of widening. A repository that
|
|
833
|
+
fails becomes a scoped warning with `fetchFailed` while the others still answer, and is retried once, at the
|
|
834
|
+
page it missed, on the next page; if the retry fails too it is dropped and reported on every later page, so one
|
|
835
|
+
that never answers can't hold `hasMore` open. A 401, or a 403 on the dashboard, is the credential and fails the
|
|
836
|
+
read; a 403 on one repository is that repository refusing the token, reported for it alone. Several states
|
|
837
|
+
(and `closed`, which is `DECLINED` plus `SUPERSEDED`) are read as every state and filtered, rather than costing
|
|
838
|
+
a request each.
|
|
705
839
|
- **Azure DevOps** — org + project scoped. Repo-scoped reads accept one org per call. Account-wide reads
|
|
706
840
|
drain every project of every org and return one aggregate page; a failed project becomes a scoped warning
|
|
707
841
|
while its siblings survive. Only Azure can narrow an account-wide issue read by `org`/`project`.
|
|
708
842
|
`resolveRepository` needs a project in the remote URL. Azure DevOps Server uses the trusted connection's
|
|
709
|
-
|
|
843
|
+
`baseUrl`, including its installation path. A repository's virtual directory must match that path and is
|
|
844
|
+
applied once; a connection addressed at the host root takes the repository's own virtual directory. An address
|
|
845
|
+
that also names a collection (`https://server/tfs/DefaultCollection`) reads that collection without repeating it:
|
|
846
|
+
discovery reports it as the one collection visible there, since Azure only lists collections at the server level,
|
|
847
|
+
and another collection's repositories need an address without the collection. Installation paths match case-insensitively, as IIS serves them. An SSH remote
|
|
848
|
+
that names no virtual directory is read against the whole address, since it can't tell a virtual directory from
|
|
849
|
+
another collection named there.
|
|
850
|
+
|
|
851
|
+
Azure DevOps Server also has the filtered searches and their counts, with the collection applied exactly once
|
|
852
|
+
whichever way the address is written. Scope names are encoded as URL segments (collections, projects,
|
|
853
|
+
repositories) or escaped as WIQL string literals (a repository's project in the work-item query), never spliced
|
|
854
|
+
into a qualifier syntax, so names with spaces or quotes are accepted there.
|
|
855
|
+
- **Work items** (`searchIssuesPage` / `countIssues`) run ONE WIQL query per page over ONE collection, with every
|
|
856
|
+
relationship OR-ed in it, so an item matching two relationships is one row and the count is the exact size of
|
|
857
|
+
the same match set. `org` names the collection; without it the repositories' collection is used, and without
|
|
858
|
+
either the only collection the account can see. A search across several collections is refused (pass `org`),
|
|
859
|
+
as is one whose repositories name a project the collection doesn't have. Repositories bound the query by
|
|
860
|
+
their project, since work items belong to projects. The page reads the first 20,000 matches (Azure's documented
|
|
861
|
+
query result limit), bounded with `$top`; past that it is `truncated` with a `provider-limit` omission carrying
|
|
862
|
+
`limit` and `sort` but no `totalCount`, and the count reports `exceedsProviderLimit: true` with no `count` rather
|
|
863
|
+
than the limit. Verified against Azure DevOps Server 2020 with 20,014 matches. A server that refuses the match set
|
|
864
|
+
even with `$top` (`VS402337`) fails the page (warning + `fetchFailed`, "narrow the search"), since no bounded query
|
|
865
|
+
could serve that order's first window; its count still reports `exceedsProviderLimit`.
|
|
866
|
+
A pagination pages through the ids its first page queried, kept while it keeps reading (5 minutes after the last
|
|
867
|
+
page, 30 at most, among the 50 most recently read paginations); every first page queries its own, so a pagination of the same query started later never
|
|
868
|
+
replaces it. A continuation whose snapshot is gone is refused (warning + `fetchFailed`) rather than resumed
|
|
869
|
+
against a fresh query, where an item moved by the `updated` order could be skipped. Restart without the cursor.
|
|
870
|
+
A cursor is bound to its query and refused under another one. `page` without a cursor walks from page 1 against
|
|
871
|
+
a fresh query. Requests use REST `api-version=5.0`, so Azure DevOps Server 2019 or later is required.
|
|
872
|
+
- **Pull requests** (`searchPullRequestsPage` / `countPullRequests`) drain every facet — each repository, or each
|
|
873
|
+
project of the `org` (every visible project when only relationships bound the search), times each
|
|
874
|
+
relationship — reading up to 1,000 pull requests per facet, then apply text, draft and dates, union by repository
|
|
875
|
+
identity (so pull request #1 in two projects stays two rows) and order the result. A pagination pages through
|
|
876
|
+
the drain its own first page read while it keeps reading (5 minutes after the last page, 30 at most, among the 50
|
|
877
|
+
most recently read paginations), from a
|
|
878
|
+
keyset cursor; a later first page of the same query drains anew without replacing it. A continuation whose drain
|
|
879
|
+
is gone, or handed to another connection, is refused like an expired work-item snapshot, since a re-drain could
|
|
880
|
+
move a pull request whose close date changed past the position already served. The count reuses the drain a
|
|
881
|
+
first page of the same query read within the last minute, and drains afresh otherwise, so a polled count stays
|
|
882
|
+
live. A facet that exceeds the drain bound makes the result `truncated` with no total, and its count `undefined`.
|
|
883
|
+
Dates that aren't `YYYY-MM-DD` are refused before anything is read, and in a count only for their own scope. A facet whose
|
|
884
|
+
read fails fails the whole search rather than serving a union with a hole in its order. Text matches the title
|
|
885
|
+
or the first 400 characters of the description (all a pull request list returns), and `updatedAfter` compares
|
|
886
|
+
Azure's close date (or creation date while open), since Azure reports no last-activity date. `itemsPerPage`
|
|
887
|
+
is per page here, not per facet. A repository name of `.` or `..` is refused rather than resolved as a path.
|
|
888
|
+
|
|
710
889
|
- **Jira (Cloud + Data Center) / Linear / Trello** — paged by **project**, not by issue: `itemsPerPage` counts projects (default
|
|
711
890
|
20), each drained in full. Passing none of `page`/`cursor`/`itemsPerPage` aggregates every matched project
|
|
712
891
|
in one page. A single project exceeding its internal drain backstop shows up as `page.truncated`.
|
|
@@ -718,11 +897,21 @@ Markdown by this package.
|
|
|
718
897
|
recovered. `hasMore` reports only untouched forward progress. A cursor can therefore remain with
|
|
719
898
|
`hasMore: false`; reusing it is an explicit manual retry of failed work, not a normal paging loop.
|
|
720
899
|
|
|
900
|
+
Self-managed descriptors keep `domain` as the normalized host and expose the configured installation address
|
|
901
|
+
in `baseUrl`. Provider requests use the selected connection's address, including during account discovery.
|
|
902
|
+
HTTPS repository resolution requires the configured host, web port, and installation path; the installation
|
|
903
|
+
prefix is removed before parsing the repository identity. Without a `connectionId`, the connection whose
|
|
904
|
+
installation path is the longest prefix of the remote resolves it (the primary on a tie); a remote under an
|
|
905
|
+
installation that an unpinned read can't reach through its own session resolves as `host-mismatch` rather
|
|
906
|
+
than through another installation's session. SSH resolution uses the configured web address and
|
|
907
|
+
port, since the SSH endpoint can use a different port and omit the web installation path. If several configured
|
|
908
|
+
web authorities share an SSH hostname, select one with `connectionId` or a trusted `domain`.
|
|
909
|
+
|
|
721
910
|
**`broadenIssues` vs `searchIssuesPage`.** `broadenIssues` now reads each org through the org-scoped
|
|
722
|
-
filtered search where the provider declares one (GitHub/GHE), so it no longer discovers
|
|
723
|
-
and no longer routes through the SDK read's recovery walk — one request per page, per org. A
|
|
724
|
-
no filtered search (Azure DevOps, GitLab) still takes the repository drain, since refusing
|
|
725
|
-
worse. It remains the read for "fan out across these orgs, whatever repos they turn out to contain", with
|
|
911
|
+
filtered search where the provider declares one (GitHub/GHE, Azure DevOps Server), so it no longer discovers
|
|
912
|
+
repositories first and no longer routes through the SDK read's recovery walk — one request per page, per org. A
|
|
913
|
+
provider with no filtered search (Azure DevOps Services, GitLab) still takes the repository drain, since refusing
|
|
914
|
+
the org would be worse. It remains the read for "fan out across these orgs, whatever repos they turn out to contain", with
|
|
726
915
|
per-provider attribution (`broadenedProviderIds` / `failedProviderIds` / `incompleteProviderIds`) that the
|
|
727
916
|
single-provider search doesn't produce; reach for `searchIssuesPage` when you want ONE scope with an order
|
|
728
917
|
you control.
|
|
@@ -156,11 +156,12 @@ was the standing argument for refusing a multi-repo "assigned to anyone" read. M
|
|
|
156
156
|
`org:gitkraken` 315. Any scope works; only the unscoped form is meaningless (6.7 M), which is what the guards
|
|
157
157
|
actually refuse.
|
|
158
158
|
|
|
159
|
-
**Provider coverage:** GitHub/GHE
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
`
|
|
159
|
+
**Provider coverage:** GitHub/GHE, and Azure DevOps Server through one collection-scoped WIQL query (#5876; see
|
|
160
|
+
[`integrations.md` §9](./integrations.md#9-per-provider-behavior-worth-designing-around) for what it declares).
|
|
161
|
+
GitLab and Azure DevOps Services declare no `issueSearch` capability, so the read is refused there rather than
|
|
162
|
+
serving an unnarrowed list — unimplemented, not impossible: GitLab maps to `search` / `updated_after` / `labels` /
|
|
163
|
+
`milestone` with one relationship per REST call (its `assignee_username` + `author_username` compose with AND, so
|
|
164
|
+
relationships must stay separate drains).
|
|
164
165
|
|
|
165
166
|
**`countPullRequests`** is the PR twin, closing the asymmetry the audit flagged: the PR side had
|
|
166
167
|
`searchPullRequestsPage` but no count probe, so an explicit "search everywhere" on PRs ran blind while the same
|
|
@@ -169,7 +170,10 @@ action on issues showed a number. It reuses GitHub's `issueCount`-on-a-zero-node
|
|
|
169
170
|
one-relationship-per-scope rules. The one PR-specific decision: a scope's `states` are counted as independent
|
|
170
171
|
searches, so the reported count is the **largest** of them (the total `searchPullRequestsPage` itself surfaces
|
|
171
172
|
via `Math.max` over facets), not their sum, and `exceedsProviderLimit` compares that max against the per-search
|
|
172
|
-
ceiling. GitHub/GHE
|
|
173
|
+
ceiling. GitHub/GHE, Bitbucket Data Center and Azure DevOps Server, matching `searchPullRequestsPage`. Bitbucket
|
|
174
|
+
Data Center counts by reading, so it reports the exact union (a floor with `lowerBound` past its first page) and
|
|
175
|
+
accepts several relationships in one scope; Azure's count is the union of the states from the same facet drain its
|
|
176
|
+
search pages through, or `undefined` past the drain bound.
|
|
173
177
|
|
|
174
178
|
**Since done:** `broadenIssues`' inner per-org read WAS swapped onto the filtered search (#5804). Only that
|
|
175
179
|
inner read changed — the fan-out keeps its own result type, per-org cursor bundle and per-provider
|
|
@@ -198,5 +202,14 @@ than a browser link; supplying both retains the one-request contract. Linear nee
|
|
|
198
202
|
Linear only; Trello refuses because its single-issue read can fall back to a capped board scan for a numeric
|
|
199
203
|
identifier, where a "not found" result cannot be distinguished from a card beyond the cap.
|
|
200
204
|
|
|
205
|
+
**Jira Data Center point reads (#5872).** The same read serves a self-hosted Jira instance once it carries the host:
|
|
206
|
+
`getTrackerIssue` takes the `domain` its paged siblings already took, and `resourceId` is the host itself (the
|
|
207
|
+
instance's single resource; one naming another host than the read resolves to is refused). It does NOT fall back to the primary connection the way the paged reads do — a
|
|
208
|
+
self-managed tracker requires a `domain` or a `connectionId` with a configured host and is refused otherwise —
|
|
209
|
+
because its proven absence is cacheable and two self-hosted instances routinely issue the same keys, so an answer
|
|
210
|
+
from whichever host is primary would be cached under a key naming a different instance. The branch-association
|
|
211
|
+
resolver (`getIssueFromGitConfigEntityIdentifier`) follows the same rule from the other side: its resolver receives
|
|
212
|
+
the identifier's `domain`, and a Jira Data Center identifier without one is dropped rather than resolved.
|
|
213
|
+
|
|
201
214
|
**Kepler-side follow-up:** `ProviderScopeFilter` carries a single `repo?: string` today and needs the criteria
|
|
202
215
|
set; the `provider-data` adapter then routes "All visible" to `searchIssuesPage` + `countIssues`.
|
package/package.json
CHANGED