@gitkraken/core-gitlens 0.5.114 → 0.5.115
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 +26 -1
- package/dist/plus/git-github/api/github.d.ts.map +1 -1
- package/dist/plus/git-github/api/github.js +37 -37
- package/dist/plus/git-github/api/github.js.map +1 -1
- package/dist/plus/integrations/collectionMetadata.d.ts +2 -0
- package/dist/plus/integrations/collectionMetadata.d.ts.map +1 -1
- package/dist/plus/integrations/collectionMetadata.js +17 -1
- package/dist/plus/integrations/collectionMetadata.js.map +1 -1
- package/dist/plus/integrations/context.d.ts +4 -1
- package/dist/plus/integrations/context.d.ts.map +1 -1
- package/dist/plus/integrations/index.d.ts +1 -0
- package/dist/plus/integrations/index.d.ts.map +1 -1
- package/dist/plus/integrations/integrationService.d.ts +9 -1
- package/dist/plus/integrations/integrationService.d.ts.map +1 -1
- package/dist/plus/integrations/integrationService.js +8 -4
- package/dist/plus/integrations/integrationService.js.map +1 -1
- package/dist/plus/integrations/manager.d.ts +22 -0
- package/dist/plus/integrations/manager.d.ts.map +1 -1
- package/dist/plus/integrations/models/gitHostIntegration.d.ts +22 -26
- package/dist/plus/integrations/models/gitHostIntegration.d.ts.map +1 -1
- package/dist/plus/integrations/models/gitHostIntegration.js +92 -47
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
- package/dist/plus/integrations/models/integration.d.ts +9 -0
- package/dist/plus/integrations/models/integration.d.ts.map +1 -1
- package/dist/plus/integrations/models/integration.js +52 -19
- package/dist/plus/integrations/models/integration.js.map +1 -1
- package/dist/plus/integrations/models/issueCache.d.ts +16 -0
- package/dist/plus/integrations/models/issueCache.d.ts.map +1 -0
- package/dist/plus/integrations/models/issueCache.js +9 -0
- package/dist/plus/integrations/models/issueCache.js.map +1 -0
- package/dist/plus/integrations/models/issueReads.d.ts +13 -0
- package/dist/plus/integrations/models/issueReads.d.ts.map +1 -1
- package/dist/plus/integrations/models/issuesIntegration.d.ts +11 -13
- package/dist/plus/integrations/models/issuesIntegration.d.ts.map +1 -1
- package/dist/plus/integrations/models/issuesIntegration.js +15 -1
- package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOps.d.ts +3 -5
- package/dist/plus/integrations/providers/azureDevOps.d.ts.map +1 -1
- package/dist/plus/integrations/providers/azureDevOps.js +9 -8
- package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket-server.d.ts +3 -5
- package/dist/plus/integrations/providers/bitbucket-server.d.ts.map +1 -1
- package/dist/plus/integrations/providers/bitbucket-server.js +2 -2
- package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket.d.ts +3 -5
- package/dist/plus/integrations/providers/bitbucket.d.ts.map +1 -1
- package/dist/plus/integrations/providers/bitbucket.js +2 -1
- package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
- package/dist/plus/integrations/providers/github.d.ts +3 -5
- package/dist/plus/integrations/providers/github.d.ts.map +1 -1
- package/dist/plus/integrations/providers/github.js +3 -3
- package/dist/plus/integrations/providers/github.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab.d.ts +3 -5
- package/dist/plus/integrations/providers/gitlab.d.ts.map +1 -1
- package/dist/plus/integrations/providers/gitlab.js +2 -2
- package/dist/plus/integrations/providers/gitlab.js.map +1 -1
- package/dist/plus/integrations/providers/jira.d.ts +3 -7
- package/dist/plus/integrations/providers/jira.d.ts.map +1 -1
- package/dist/plus/integrations/providers/jira.js +35 -22
- package/dist/plus/integrations/providers/jira.js.map +1 -1
- package/dist/plus/integrations/providers/jiraIssueByKey.d.ts +7 -0
- package/dist/plus/integrations/providers/jiraIssueByKey.d.ts.map +1 -0
- package/dist/plus/integrations/providers/jiraIssueByKey.js +102 -0
- package/dist/plus/integrations/providers/jiraIssueByKey.js.map +1 -0
- package/dist/plus/integrations/providers/linear.d.ts +3 -7
- package/dist/plus/integrations/providers/linear.d.ts.map +1 -1
- package/dist/plus/integrations/providers/linear.js +23 -22
- package/dist/plus/integrations/providers/linear.js.map +1 -1
- package/dist/plus/integrations/providers/models.d.ts +3 -1
- package/dist/plus/integrations/providers/models.d.ts.map +1 -1
- package/dist/plus/integrations/providers/models.js +10 -4
- package/dist/plus/integrations/providers/models.js.map +1 -1
- package/dist/plus/integrations/providers/providerErrors.d.ts +7 -0
- package/dist/plus/integrations/providers/providerErrors.d.ts.map +1 -0
- package/dist/plus/integrations/providers/providerErrors.js +91 -0
- package/dist/plus/integrations/providers/providerErrors.js.map +1 -0
- package/dist/plus/integrations/providers/providersApi.d.ts +3 -2
- package/dist/plus/integrations/providers/providersApi.d.ts.map +1 -1
- package/dist/plus/integrations/providers/providersApi.js +18 -52
- package/dist/plus/integrations/providers/providersApi.js.map +1 -1
- package/dist/plus/integrations/providers/trello.d.ts +2 -7
- package/dist/plus/integrations/providers/trello.d.ts.map +1 -1
- package/dist/plus/integrations/providers/trello.js +3 -1
- package/dist/plus/integrations/providers/trello.js.map +1 -1
- package/dist/plus/integrations/providers/utils/providerPaging.d.ts +2 -0
- package/dist/plus/integrations/providers/utils/providerPaging.d.ts.map +1 -1
- package/dist/plus/integrations/providers/utils/providerPaging.js +12 -7
- package/dist/plus/integrations/providers/utils/providerPaging.js.map +1 -1
- package/dist/plus/integrations/reads/issueTracker.d.ts.map +1 -1
- package/dist/plus/integrations/reads/issueTracker.js +23 -17
- package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
- package/dist/plus/integrations/reads/trackerIssue.d.ts +21 -0
- package/dist/plus/integrations/reads/trackerIssue.d.ts.map +1 -0
- package/dist/plus/integrations/reads/trackerIssue.js +51 -0
- package/dist/plus/integrations/reads/trackerIssue.js.map +1 -0
- package/dist/plus/integrations/reads/warnings.d.ts +2 -15
- package/dist/plus/integrations/reads/warnings.d.ts.map +1 -1
- package/dist/plus/integrations/reads/warnings.js +19 -1
- package/dist/plus/integrations/reads/warnings.js.map +1 -1
- package/dist/plus/integrations/results.d.ts +4 -20
- package/dist/plus/integrations/results.d.ts.map +1 -1
- package/dist/plus/integrations/results.js.map +1 -1
- package/dist/utils/promise.d.ts +2 -0
- package/dist/utils/promise.d.ts.map +1 -1
- package/dist/utils/promise.js +11 -0
- package/dist/utils/promise.js.map +1 -1
- package/docs/integrations.md +37 -26
- package/docs/kepler-read-api-parity.md +13 -0
- package/package.json +2 -2
- package/src/plus/git-github/api/github.ts +51 -58
- package/src/plus/integrations/collectionMetadata.ts +23 -1
- package/src/plus/integrations/context.ts +1 -1
- package/src/plus/integrations/index.ts +1 -0
- package/src/plus/integrations/integrationService.ts +14 -4
- package/src/plus/integrations/manager.ts +22 -0
- package/src/plus/integrations/models/gitHostIntegration.ts +117 -129
- package/src/plus/integrations/models/integration.ts +56 -22
- package/src/plus/integrations/models/issueCache.ts +29 -0
- package/src/plus/integrations/models/issueReads.ts +15 -0
- package/src/plus/integrations/models/issuesIntegration.ts +38 -8
- package/src/plus/integrations/providers/azureDevOps.ts +16 -13
- package/src/plus/integrations/providers/bitbucket-server.ts +4 -6
- package/src/plus/integrations/providers/bitbucket.ts +3 -4
- package/src/plus/integrations/providers/github.ts +5 -7
- package/src/plus/integrations/providers/gitlab.ts +4 -6
- package/src/plus/integrations/providers/jira.ts +52 -26
- package/src/plus/integrations/providers/jiraIssueByKey.ts +155 -0
- package/src/plus/integrations/providers/linear.ts +38 -25
- package/src/plus/integrations/providers/models.ts +17 -5
- package/src/plus/integrations/providers/providerErrors.ts +115 -0
- package/src/plus/integrations/providers/providersApi.ts +26 -68
- package/src/plus/integrations/providers/trello.ts +5 -4
- package/src/plus/integrations/providers/utils/providerPaging.ts +14 -7
- package/src/plus/integrations/reads/issueTracker.ts +26 -24
- package/src/plus/integrations/reads/trackerIssue.ts +105 -0
- package/src/plus/integrations/reads/warnings.ts +23 -17
- package/src/plus/integrations/results.ts +4 -20
- package/src/utils/promise.ts +15 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { IssueShape } from '../../../git/models/issue.js';
|
|
2
|
+
import type { IntegrationIds } from '../constants.js';
|
|
3
|
+
import { IssuesCloudHostIntegrationId } from '../constants.js';
|
|
4
|
+
import { isIssuesIntegration } from '../models/issuesIntegration.js';
|
|
5
|
+
import type { ProviderResult, ProviderWarning } from '../results.js';
|
|
6
|
+
import { isIssuesHostIntegrationId } from '../utils/integration.utils.js';
|
|
7
|
+
import type { ProviderReadContext } from './context.js';
|
|
8
|
+
import { runCaptured } from './drains.js';
|
|
9
|
+
import { issueTrackerOnlySurfaceWarning, otherWarning } from './warnings.js';
|
|
10
|
+
|
|
11
|
+
export interface TrackerIssueResult {
|
|
12
|
+
key: string;
|
|
13
|
+
/**
|
|
14
|
+
* The resolved issue, or `undefined` when it provably does not exist or is not visible to this connection.
|
|
15
|
+
* A failed read returns no item and sets `fetchFailed`.
|
|
16
|
+
*/
|
|
17
|
+
issue?: IssueShape;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Issue trackers are cloud-only, so this read takes no `domain`. */
|
|
21
|
+
export async function getTrackerIssue(
|
|
22
|
+
ctx: ProviderReadContext,
|
|
23
|
+
options: {
|
|
24
|
+
providerId: IntegrationIds;
|
|
25
|
+
resourceId: string;
|
|
26
|
+
resourceUrl?: string;
|
|
27
|
+
key: string;
|
|
28
|
+
connectionId?: string;
|
|
29
|
+
},
|
|
30
|
+
): Promise<ProviderResult<TrackerIssueResult>> {
|
|
31
|
+
const refused = (warning: ProviderWarning): ProviderResult<TrackerIssueResult> => ({
|
|
32
|
+
items: [],
|
|
33
|
+
warnings: [warning],
|
|
34
|
+
fetchFailed: true,
|
|
35
|
+
});
|
|
36
|
+
const surface = 'Issue resolution by key';
|
|
37
|
+
|
|
38
|
+
if (!isIssuesHostIntegrationId(options.providerId)) {
|
|
39
|
+
return refused(issueTrackerOnlySurfaceWarning(options.providerId, options.connectionId, surface));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (options.resourceId.trim().length === 0) {
|
|
43
|
+
return refused(
|
|
44
|
+
otherWarning(options.providerId, undefined, options.connectionId, `${surface} requires a resource id.`),
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (options.key.trim().length === 0) {
|
|
49
|
+
return refused(
|
|
50
|
+
otherWarning(options.providerId, undefined, options.connectionId, `${surface} requires an issue key.`),
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const resourceUrl = options.resourceUrl?.trim() || undefined;
|
|
55
|
+
if (options.providerId === IssuesCloudHostIntegrationId.Jira && resourceUrl == null) {
|
|
56
|
+
return refused(
|
|
57
|
+
otherWarning(
|
|
58
|
+
options.providerId,
|
|
59
|
+
undefined,
|
|
60
|
+
options.connectionId,
|
|
61
|
+
`${surface} requires the Jira resource URL so the result contains a browser link without resource discovery.`,
|
|
62
|
+
),
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const integration = await ctx.getIntegrationForRead(options.providerId, options.connectionId);
|
|
67
|
+
if (integration == null) {
|
|
68
|
+
const early = ctx.earlyReturnConnectionWarnings(options.providerId, options.connectionId);
|
|
69
|
+
return { items: [], warnings: early.warnings, fetchFailed: early.fetchFailed || undefined };
|
|
70
|
+
}
|
|
71
|
+
if (!isIssuesIntegration(integration)) {
|
|
72
|
+
return refused(issueTrackerOnlySurfaceWarning(options.providerId, options.connectionId, surface));
|
|
73
|
+
}
|
|
74
|
+
if (!integration.supportsIssueLookupByResourceId) {
|
|
75
|
+
return refused(
|
|
76
|
+
otherWarning(
|
|
77
|
+
options.providerId,
|
|
78
|
+
undefined,
|
|
79
|
+
options.connectionId,
|
|
80
|
+
`${surface} is not supported by '${options.providerId}'; its single-issue read cannot prove an absence, so a miss would not be safe to cache.`,
|
|
81
|
+
),
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const domain = ctx.domainForRead(integration, options.providerId, options.connectionId);
|
|
86
|
+
const issue = await runCaptured(
|
|
87
|
+
options.providerId,
|
|
88
|
+
domain,
|
|
89
|
+
options.connectionId,
|
|
90
|
+
() =>
|
|
91
|
+
integration.getIssueByResourceIdResult(options.resourceId, options.key, {
|
|
92
|
+
connectionId: options.connectionId,
|
|
93
|
+
resourceUrl: resourceUrl,
|
|
94
|
+
}),
|
|
95
|
+
{ warnOnMissingSession: true },
|
|
96
|
+
);
|
|
97
|
+
if (issue.warning != null) {
|
|
98
|
+
return refused(issue.warning);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
items: [{ key: options.key, ...(issue.value != null ? { issue: issue.value } : {}) }],
|
|
103
|
+
warnings: [],
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -8,7 +8,7 @@ import type {
|
|
|
8
8
|
PullRequestSorting,
|
|
9
9
|
} from '../providerFilters.js';
|
|
10
10
|
import { providersMetadata } from '../providers/models.js';
|
|
11
|
-
import type { ProviderWarning } from '../results.js';
|
|
11
|
+
import type { ProviderWarning, ProviderWarningOmissionRecovery } from '../results.js';
|
|
12
12
|
import type { IssueSearchCriteriaRejection, PullRequestSearchCriteriaRejection } from './filters.js';
|
|
13
13
|
import type { UnmergeableIssueSort, UnsupportedIssueSortRejection } from './ordering.js';
|
|
14
14
|
|
|
@@ -101,21 +101,23 @@ export function issueTrackerOnlySurfaceWarning(
|
|
|
101
101
|
);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
/**
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
104
|
+
/** Why a facade-driven read returned fewer results than requested. */
|
|
105
|
+
export type IncompleteReadCause = 'interrupted' | 'page-budget' | 'exhausted' | 'scope-too-large';
|
|
106
|
+
|
|
107
|
+
function recoveryForIncompleteReadCause(cause: IncompleteReadCause): ProviderWarningOmissionRecovery {
|
|
108
|
+
switch (cause) {
|
|
109
|
+
case 'page-budget':
|
|
110
|
+
return 'page-budget';
|
|
111
|
+
case 'scope-too-large':
|
|
112
|
+
return 'narrow-scope';
|
|
113
|
+
case 'interrupted':
|
|
114
|
+
case 'exhausted':
|
|
115
|
+
return 'none';
|
|
116
|
+
default:
|
|
117
|
+
cause satisfies never;
|
|
118
|
+
return 'none';
|
|
119
|
+
}
|
|
120
|
+
}
|
|
119
121
|
|
|
120
122
|
/**
|
|
121
123
|
* Builds the warning for a read that returned less than everything, carrying the two facts a consumer cannot
|
|
@@ -143,7 +145,7 @@ export function incompleteReadWarning(
|
|
|
143
145
|
...warning,
|
|
144
146
|
omission: {
|
|
145
147
|
kind: 'pagination-incomplete',
|
|
146
|
-
recovery: cause
|
|
148
|
+
recovery: recoveryForIncompleteReadCause(cause),
|
|
147
149
|
},
|
|
148
150
|
};
|
|
149
151
|
}
|
|
@@ -192,6 +194,10 @@ function truncationMessage(id: IntegrationIds, readKind: TruncatedReadKind, caus
|
|
|
192
194
|
return `${readKind} read for '${id}' stopped at its page budget; more results can be read by raising it.`;
|
|
193
195
|
case 'exhausted':
|
|
194
196
|
return `${readKind} read for '${id}' was truncated and cannot be continued; results may be incomplete.`;
|
|
197
|
+
case 'scope-too-large':
|
|
198
|
+
// Says what is true — the scope is larger than a read of it — rather than blaming the provider for a
|
|
199
|
+
// ceiling that is ours, and names the remedy that exists, since no retry or budget has one.
|
|
200
|
+
return `${readKind} read for '${id}' covers more than one read can return; narrow the scope to read the rest.`;
|
|
195
201
|
}
|
|
196
202
|
// No `default`: `IncompleteReadCause` is declared in this file, so `noImplicitReturns` already fails the
|
|
197
203
|
// build here if a cause is added without its own wording. (`collectionOmissionMessage`'s `satisfies never`
|
|
@@ -35,27 +35,11 @@ export type ProviderWarningKind = 'auth' | 'rate-limit' | 'not-found' | 'no-conn
|
|
|
35
35
|
export type ProviderWarningOmissionKind = 'provider-limit' | 'recovery-budget' | 'pagination-incomplete';
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* `
|
|
41
|
-
* that stopped at a caller-settable page budget and a provider that advertised another page without a usable
|
|
42
|
-
* cursor are both `pagination-incomplete`, but only the first can be fetched. A consumer offering a "load
|
|
43
|
-
* more" affordance gates it on this, never on `kind`.
|
|
44
|
-
*
|
|
45
|
-
* - `none`: nothing the consumer can call returns the missing items — a provider-enforced cap, an internal
|
|
46
|
-
* budget it does not control, or a continuation the provider refused to hand back. Say the results are
|
|
47
|
-
* capped; do not offer to fetch more.
|
|
48
|
-
* - `page-budget`: re-run the SAME read with a higher page budget (`maxPages` on the sweep options). Note this
|
|
49
|
-
* re-reads from the start rather than continuing — a sweep exposes no cursor — so it is a deliberate,
|
|
50
|
-
* user-initiated action, not something to retry automatically.
|
|
51
|
-
*
|
|
52
|
-
* Required, not optional: an absent value would be indistinguishable from `none` while actually meaning "this
|
|
53
|
-
* producer didn't say", which is the ambiguity {@link ProviderWarning.omission} exists to remove. And a
|
|
54
|
-
* conservative union on purpose — it names only what a producer can PROVE. A value is added when some layer
|
|
55
|
-
* can vouch for it, never so that a plausible-looking case has something to map to; see
|
|
56
|
-
* `collectionMetadata.ts` for the SDK shape that looks recoverable and is not.
|
|
38
|
+
* How a consumer can recover omitted results. `page-budget` reruns with a larger budget; `narrow-scope`
|
|
39
|
+
* requests a smaller server-side scope; `none` promises neither. Switch on the exact value because only
|
|
40
|
+
* `page-budget` is a fetch-more action.
|
|
57
41
|
*/
|
|
58
|
-
export type ProviderWarningOmissionRecovery = 'none' | 'page-budget';
|
|
42
|
+
export type ProviderWarningOmissionRecovery = 'none' | 'page-budget' | 'narrow-scope';
|
|
59
43
|
|
|
60
44
|
/** Which repository / project / resource an omission is attributed to. All fields optional; a scope may name none. */
|
|
61
45
|
export interface ProviderWarningOmissionScope {
|
package/src/utils/promise.ts
CHANGED
|
@@ -121,6 +121,21 @@ export async function mapBounded<T, R>(
|
|
|
121
121
|
return results;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
/** Settles each task without stopping the sliding window when one of them rejects. */
|
|
125
|
+
export function mapSettledBounded<T, R>(
|
|
126
|
+
items: readonly T[],
|
|
127
|
+
concurrency: number,
|
|
128
|
+
task: (item: T, index: number) => Promise<R>,
|
|
129
|
+
): Promise<PromiseSettledResult<Awaited<R>>[]> {
|
|
130
|
+
return mapBounded(items, concurrency, async (item, index): Promise<PromiseSettledResult<Awaited<R>>> => {
|
|
131
|
+
try {
|
|
132
|
+
return { status: 'fulfilled', value: await task(item, index) };
|
|
133
|
+
} catch (reason) {
|
|
134
|
+
return { status: 'rejected', reason: reason };
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
124
139
|
export class PromiseCancelledError<T extends Promise<any> = Promise<any>> extends Error {
|
|
125
140
|
constructor(
|
|
126
141
|
public readonly promise: T,
|