@gitkraken/core-gitlens 0.9.3 → 0.9.5

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.
Files changed (160) hide show
  1. package/CHANGELOG.md +34 -1
  2. package/dist/git/models/issue.d.ts +25 -2
  3. package/dist/git/models/issue.js +3 -1
  4. package/dist/git/models/issue.js.map +1 -1
  5. package/dist/git/models/pullRequest.d.ts +55 -5
  6. package/dist/git/models/pullRequest.js +5 -1
  7. package/dist/git/models/pullRequest.js.map +1 -1
  8. package/dist/git/utils/issue.utils.d.ts +4 -0
  9. package/dist/git/utils/issue.utils.js +4 -0
  10. package/dist/git/utils/issue.utils.js.map +1 -1
  11. package/dist/git/utils/pullRequest.utils.d.ts +4 -0
  12. package/dist/git/utils/pullRequest.utils.js +8 -0
  13. package/dist/git/utils/pullRequest.utils.js.map +1 -1
  14. package/dist/plus/git-github/api/github.d.ts +64 -4
  15. package/dist/plus/git-github/api/github.js +232 -15
  16. package/dist/plus/git-github/api/github.js.map +1 -1
  17. package/dist/plus/git-github/models.d.ts +48 -6
  18. package/dist/plus/git-github/models.js +11 -10
  19. package/dist/plus/git-github/models.js.map +1 -1
  20. package/dist/plus/integrations/fieldPresence.d.ts +75 -0
  21. package/dist/plus/integrations/fieldPresence.js +381 -0
  22. package/dist/plus/integrations/fieldPresence.js.map +1 -0
  23. package/dist/plus/integrations/index.d.ts +6 -4
  24. package/dist/plus/integrations/index.js +2 -1
  25. package/dist/plus/integrations/index.js.map +1 -1
  26. package/dist/plus/integrations/integrationService.d.ts +13 -4
  27. package/dist/plus/integrations/integrationService.js.map +1 -1
  28. package/dist/plus/integrations/manager.d.ts +62 -7
  29. package/dist/plus/integrations/models/gitHostIntegration.d.ts +103 -9
  30. package/dist/plus/integrations/models/gitHostIntegration.js +116 -5
  31. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  32. package/dist/plus/integrations/models/integration.d.ts +91 -4
  33. package/dist/plus/integrations/models/integration.js +56 -7
  34. package/dist/plus/integrations/models/integration.js.map +1 -1
  35. package/dist/plus/integrations/models/issueReads.d.ts +14 -0
  36. package/dist/plus/integrations/models/issuesIntegration.d.ts +44 -3
  37. package/dist/plus/integrations/models/issuesIntegration.js +51 -1
  38. package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
  39. package/dist/plus/integrations/providers/azure/azure.js +3 -3
  40. package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
  41. package/dist/plus/integrations/providers/azure/models.d.ts +36 -4
  42. package/dist/plus/integrations/providers/azure/models.js +118 -8
  43. package/dist/plus/integrations/providers/azure/models.js.map +1 -1
  44. package/dist/plus/integrations/providers/azureDevOps.d.ts +102 -5
  45. package/dist/plus/integrations/providers/azureDevOps.js +264 -45
  46. package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
  47. package/dist/plus/integrations/providers/azureDevOpsServer.d.ts +30 -6
  48. package/dist/plus/integrations/providers/azureDevOpsServer.js +82 -21
  49. package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -1
  50. package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts +21 -1
  51. package/dist/plus/integrations/providers/bitbucket/bitbucket.js +74 -10
  52. package/dist/plus/integrations/providers/bitbucket/bitbucket.js.map +1 -1
  53. package/dist/plus/integrations/providers/bitbucket/models.d.ts +45 -8
  54. package/dist/plus/integrations/providers/bitbucket/models.js +32 -9
  55. package/dist/plus/integrations/providers/bitbucket/models.js.map +1 -1
  56. package/dist/plus/integrations/providers/bitbucket-server/models.d.ts +2 -6
  57. package/dist/plus/integrations/providers/bitbucket-server/models.js +1 -3
  58. package/dist/plus/integrations/providers/bitbucket-server/models.js.map +1 -1
  59. package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.d.ts +3 -1
  60. package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js +4 -1
  61. package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js.map +1 -1
  62. package/dist/plus/integrations/providers/bitbucket-server.d.ts +2 -2
  63. package/dist/plus/integrations/providers/bitbucket-server.js +7 -5
  64. package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
  65. package/dist/plus/integrations/providers/bitbucket.d.ts +22 -2
  66. package/dist/plus/integrations/providers/bitbucket.js +29 -6
  67. package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
  68. package/dist/plus/integrations/providers/github.d.ts +40 -3
  69. package/dist/plus/integrations/providers/github.js +133 -11
  70. package/dist/plus/integrations/providers/github.js.map +1 -1
  71. package/dist/plus/integrations/providers/gitlab/gitlab.d.ts +34 -1
  72. package/dist/plus/integrations/providers/gitlab/gitlab.js +118 -4
  73. package/dist/plus/integrations/providers/gitlab/gitlab.js.map +1 -1
  74. package/dist/plus/integrations/providers/gitlab/models.d.ts +70 -5
  75. package/dist/plus/integrations/providers/gitlab/models.js +106 -13
  76. package/dist/plus/integrations/providers/gitlab/models.js.map +1 -1
  77. package/dist/plus/integrations/providers/gitlab.d.ts +31 -2
  78. package/dist/plus/integrations/providers/gitlab.js +48 -8
  79. package/dist/plus/integrations/providers/gitlab.js.map +1 -1
  80. package/dist/plus/integrations/providers/jira-server.d.ts +3 -2
  81. package/dist/plus/integrations/providers/jira-server.js +18 -9
  82. package/dist/plus/integrations/providers/jira-server.js.map +1 -1
  83. package/dist/plus/integrations/providers/jira.d.ts +26 -2
  84. package/dist/plus/integrations/providers/jira.js +120 -9
  85. package/dist/plus/integrations/providers/jira.js.map +1 -1
  86. package/dist/plus/integrations/providers/jiraIssueByKey.d.ts +79 -0
  87. package/dist/plus/integrations/providers/jiraIssueByKey.js +58 -7
  88. package/dist/plus/integrations/providers/jiraIssueByKey.js.map +1 -1
  89. package/dist/plus/integrations/providers/linear.d.ts +19 -1
  90. package/dist/plus/integrations/providers/linear.js +105 -7
  91. package/dist/plus/integrations/providers/linear.js.map +1 -1
  92. package/dist/plus/integrations/providers/linearIssuesEtag.d.ts +42 -0
  93. package/dist/plus/integrations/providers/linearIssuesEtag.js +94 -0
  94. package/dist/plus/integrations/providers/linearIssuesEtag.js.map +1 -0
  95. package/dist/plus/integrations/providers/models.d.ts +70 -8
  96. package/dist/plus/integrations/providers/models.js +59 -21
  97. package/dist/plus/integrations/providers/models.js.map +1 -1
  98. package/dist/plus/integrations/providers/providerErrors.js +8 -1
  99. package/dist/plus/integrations/providers/providerErrors.js.map +1 -1
  100. package/dist/plus/integrations/providers/providersApi.d.ts +70 -4
  101. package/dist/plus/integrations/providers/providersApi.js +148 -4
  102. package/dist/plus/integrations/providers/providersApi.js.map +1 -1
  103. package/dist/plus/integrations/providers/pullRequestReviews.d.ts +13 -0
  104. package/dist/plus/integrations/providers/pullRequestReviews.js +30 -6
  105. package/dist/plus/integrations/providers/pullRequestReviews.js.map +1 -1
  106. package/dist/plus/integrations/providers/trello.js +11 -7
  107. package/dist/plus/integrations/providers/trello.js.map +1 -1
  108. package/dist/plus/integrations/providers/utils/providerPaging.d.ts +11 -0
  109. package/dist/plus/integrations/providers/utils/providerPaging.js +47 -1
  110. package/dist/plus/integrations/providers/utils/providerPaging.js.map +1 -1
  111. package/dist/plus/integrations/providers/utils.d.ts +1 -1
  112. package/dist/plus/integrations/reads/batchEtags.d.ts +69 -0
  113. package/dist/plus/integrations/reads/batchEtags.js +114 -0
  114. package/dist/plus/integrations/reads/batchEtags.js.map +1 -0
  115. package/dist/plus/integrations/reads/counts.js +2 -2
  116. package/dist/plus/integrations/reads/counts.js.map +1 -1
  117. package/dist/plus/integrations/reads/currentAccount.js +2 -2
  118. package/dist/plus/integrations/reads/currentAccount.js.map +1 -1
  119. package/dist/plus/integrations/reads/cursors.d.ts +8 -0
  120. package/dist/plus/integrations/reads/cursors.js +5 -3
  121. package/dist/plus/integrations/reads/cursors.js.map +1 -1
  122. package/dist/plus/integrations/reads/drains.d.ts +13 -4
  123. package/dist/plus/integrations/reads/drains.js +29 -5
  124. package/dist/plus/integrations/reads/drains.js.map +1 -1
  125. package/dist/plus/integrations/reads/etag.d.ts +26 -0
  126. package/dist/plus/integrations/reads/etag.js +108 -0
  127. package/dist/plus/integrations/reads/etag.js.map +1 -0
  128. package/dist/plus/integrations/reads/filters.d.ts +8 -0
  129. package/dist/plus/integrations/reads/filters.js +2 -1
  130. package/dist/plus/integrations/reads/filters.js.map +1 -1
  131. package/dist/plus/integrations/reads/hierarchy.js +3 -3
  132. package/dist/plus/integrations/reads/hierarchy.js.map +1 -1
  133. package/dist/plus/integrations/reads/issueBatch.d.ts +47 -16
  134. package/dist/plus/integrations/reads/issueBatch.js +55 -87
  135. package/dist/plus/integrations/reads/issueBatch.js.map +1 -1
  136. package/dist/plus/integrations/reads/issueTracker.d.ts +10 -2
  137. package/dist/plus/integrations/reads/issueTracker.js +23 -6
  138. package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
  139. package/dist/plus/integrations/reads/issues.d.ts +1 -1
  140. package/dist/plus/integrations/reads/issues.js +4 -4
  141. package/dist/plus/integrations/reads/issues.js.map +1 -1
  142. package/dist/plus/integrations/reads/pullRequestBatch.d.ts +44 -6
  143. package/dist/plus/integrations/reads/pullRequestBatch.js +31 -34
  144. package/dist/plus/integrations/reads/pullRequestBatch.js.map +1 -1
  145. package/dist/plus/integrations/reads/pullRequestBranches.d.ts +5 -2
  146. package/dist/plus/integrations/reads/pullRequestBranches.js +4 -3
  147. package/dist/plus/integrations/reads/pullRequestBranches.js.map +1 -1
  148. package/dist/plus/integrations/reads/pullRequests.js +8 -4
  149. package/dist/plus/integrations/reads/pullRequests.js.map +1 -1
  150. package/dist/plus/integrations/reads/sweeps.js +8 -4
  151. package/dist/plus/integrations/reads/sweeps.js.map +1 -1
  152. package/dist/plus/integrations/reads/warnings.d.ts +23 -8
  153. package/dist/plus/integrations/reads/warnings.js +43 -19
  154. package/dist/plus/integrations/reads/warnings.js.map +1 -1
  155. package/dist/plus/integrations/results.d.ts +12 -4
  156. package/dist/plus/integrations/results.js +2 -0
  157. package/dist/plus/integrations/results.js.map +1 -1
  158. package/docs/integrations.md +389 -23
  159. package/docs/kepler-read-api-parity.md +16 -2
  160. package/package.json +2 -2
@@ -92,6 +92,13 @@ export type IssuesForProjectOptions = {
92
92
  * no normalized issue carries; this option orders one project's query.
93
93
  */
94
94
  sort?: IssueSorting;
95
+ /**
96
+ * Which issue states to read. Omitted reads open issues only, which is every tracker's own default.
97
+ *
98
+ * Validated by the facade against `ProviderMetadata.supportsIssueStates`. A tracker that can't express a state
99
+ * (Trello) refuses anything but `'open'` rather than serving its open cards as if they were the closed ones.
100
+ */
101
+ state?: IssueStateFilter;
95
102
  };
96
103
  export type ProjectIssuesDrain = {
97
104
  values: IssueShape[];
@@ -168,6 +175,13 @@ export type SearchMyIssuesOptions = {
168
175
  */
169
176
  org?: string;
170
177
  project?: string;
178
+ /**
179
+ * Which issue states to read. Omitted reads open issues only.
180
+ *
181
+ * Honored by the issue trackers that declare `ProviderMetadata.supportsIssueStates` (Jira, Jira Data Center,
182
+ * Linear). The git hosts' account-wide reads ignore it and keep their own open-only default.
183
+ */
184
+ state?: IssueStateFilter;
171
185
  /**
172
186
  * How the provider should order the read, as `field:direction`.
173
187
  *
@@ -3,14 +3,20 @@ import { Issue, IssueShape } from "../../../git/models/issue.js";
3
3
  import { Account } from "../../../git/models/author.js";
4
4
  import { ProviderAuthenticationSession } from "../authentication/models.js";
5
5
  import { IntegrationIds } from "../constants.js";
6
- import { IssuesForProjectOptions, ProjectIssuesDrain } from "./issueReads.js";
7
- import { BatchSlot, Integration, IntegrationBase, IntegrationResult, IntegrationType } from "./integration.js";
8
6
  import { ProviderApiCollectionResult } from "../providers/models.js";
7
+ import { IssuesForProjectOptions, ProjectIssuesDrain } from "./issueReads.js";
8
+ import { BatchSlot, Integration, IntegrationBase, IntegrationResult, IntegrationType, IssueEtagFields, IssueEtagInclude } from "./integration.js";
9
9
  //#region ../plus/integrations/src/models/issuesIntegration.d.ts
10
10
  export declare function isIssuesIntegration(integration: Integration): integration is IssuesIntegration;
11
11
  export declare abstract class IssuesIntegration<ID extends IntegrationIds = IntegrationIds, T extends ResourceDescriptor = ResourceDescriptor> extends IntegrationBase<ID> {
12
12
  readonly type: IntegrationType;
13
13
  get supportsIssueLookupByResourceId(): boolean;
14
+ /**
15
+ * Whether this tracker has the cheap check behind the batch issue read's etags
16
+ * ({@link getProviderIssuesEtagFieldsByResourceId}). The read decides before calling anything, so a tracker without
17
+ * one makes one call.
18
+ */
19
+ get supportsIssueEtagsByResourceId(): boolean;
14
20
  /**
15
21
  * Result-returning wrapper for the BATCH tracker issue read: resolves several `(resourceId, identifier)` targets
16
22
  * with one {@link getProviderIssueByResourceId} request each, run with bounded concurrency. One settled slot per
@@ -20,7 +26,10 @@ export declare abstract class IssuesIntegration<ID extends IntegrationIds = Inte
20
26
  * Failure isolation happens PER TARGET, mirroring `GitHostIntegration.getPullRequestsBatchResult`: the whole
21
27
  * call counts as a failure against the integration's request-exception budget only when EVERY slot rejected,
22
28
  * and not even then when a credential that checks out was refused by each target's own resource
23
- * (`settleBatchRefusals`), so a batch of mostly-good targets never spends more than one strike.
29
+ * (`settleBatchRefusals`), so a batch of mostly-good targets never spends more than one strike. A batch read with
30
+ * etags makes up to two such calls (a full read of the targets without an etag, and a full read of the ones that
31
+ * changed), so it can spend two; its cheap check ({@link getIssuesEtagFieldsByResourceIdBatchResult}) spends
32
+ * nothing unless the credential is refused.
24
33
  *
25
34
  * Uncached on purpose: the caller owns caching, as with the git hosts' batch reads.
26
35
  */
@@ -30,6 +39,38 @@ export declare abstract class IssuesIntegration<ID extends IntegrationIds = Inte
30
39
  resourceUrl?: string;
31
40
  }[], connectionId?: string): Promise<IntegrationResult<BatchSlot<IssueShape | undefined>[] | undefined>>;
32
41
  protected getProviderIssueByResourceId?(_session: ProviderAuthenticationSession, _resourceId: string, _id: string, _resourceUrl: string | undefined): Promise<Issue | undefined>;
42
+ /**
43
+ * Result-returning wrapper for the cheap check behind the batch tracker issue read's etags: each target's change
44
+ * state ({@link IssueEtagFields}), in ONE call to {@link getProviderIssuesEtagFieldsByResourceId}, which is handed
45
+ * `options.etagIncludes` as the git hosts' check is. The slots mean
46
+ * what {@link getIssuesByResourceIdBatchResult}'s do — `fulfilled` with `undefined` is a PROVEN ABSENCE, `rejected`
47
+ * means that target could not be checked. Failures are judged and budgeted as in
48
+ * `GitHostIntegration.getIssuesEtagFieldsResult`: every slot comes back as it settled, even when none answered, and
49
+ * only a refused credential fails the call or spends a strike.
50
+ */
51
+ getIssuesEtagFieldsByResourceIdBatchResult(targets: readonly {
52
+ resourceId: string;
53
+ identifier: string;
54
+ resourceUrl?: string;
55
+ }[], options: {
56
+ etagIncludes?: readonly IssueEtagInclude[];
57
+ }, connectionId?: string): Promise<IntegrationResult<BatchSlot<IssueEtagFields | undefined>[] | undefined>>;
58
+ /**
59
+ * OPTIONAL: the cheap check behind the batch tracker issue read's etags — one settled slot per input target, in
60
+ * order, holding the issue's change state in the vocabulary {@link getProviderIssueByResourceId}'s issues end in,
61
+ * so both reads compute the same etag. `fulfilled` with `undefined` is a PROVEN ABSENCE, as there; a tracker whose
62
+ * cheap read can't prove one rejects the slot instead, so the full read decides. `undefined` declines the whole
63
+ * check, sending every target to the full read without counting as a failure. A tracker implements this only
64
+ * where it is cheaper than the full read. No tracker's row carries a real reaction count, so `'reactions'` in
65
+ * `options.etagIncludes` reads nothing here.
66
+ */
67
+ protected getProviderIssuesEtagFieldsByResourceId?(session: ProviderAuthenticationSession, targets: readonly {
68
+ resourceId: string;
69
+ identifier: string;
70
+ resourceUrl?: string;
71
+ }[], options: {
72
+ etagIncludes?: readonly IssueEtagInclude[];
73
+ }): Promise<PromiseSettledResult<IssueEtagFields | undefined>[] | undefined>;
33
74
  getAccountForResource(resource: T, connectionId?: string): Promise<Account | undefined>;
34
75
  /**
35
76
  * Result-returning core of {@link getAccountForResource}. Recovers a thrown error into `{ error }` so
@@ -16,6 +16,14 @@ var IssuesIntegration = class extends IntegrationBase {
16
16
  return this.getProviderIssueByResourceId != null;
17
17
  }
18
18
  /**
19
+ * Whether this tracker has the cheap check behind the batch issue read's etags
20
+ * ({@link getProviderIssuesEtagFieldsByResourceId}). The read decides before calling anything, so a tracker without
21
+ * one makes one call.
22
+ */
23
+ get supportsIssueEtagsByResourceId() {
24
+ return this.getProviderIssuesEtagFieldsByResourceId != null;
25
+ }
26
+ /**
19
27
  * Result-returning wrapper for the BATCH tracker issue read: resolves several `(resourceId, identifier)` targets
20
28
  * with one {@link getProviderIssueByResourceId} request each, run with bounded concurrency. One settled slot per
21
29
  * input target: `fulfilled` with `undefined` means the issue does not exist or is not visible to this token;
@@ -24,7 +32,10 @@ var IssuesIntegration = class extends IntegrationBase {
24
32
  * Failure isolation happens PER TARGET, mirroring `GitHostIntegration.getPullRequestsBatchResult`: the whole
25
33
  * call counts as a failure against the integration's request-exception budget only when EVERY slot rejected,
26
34
  * and not even then when a credential that checks out was refused by each target's own resource
27
- * (`settleBatchRefusals`), so a batch of mostly-good targets never spends more than one strike.
35
+ * (`settleBatchRefusals`), so a batch of mostly-good targets never spends more than one strike. A batch read with
36
+ * etags makes up to two such calls (a full read of the targets without an etag, and a full read of the ones that
37
+ * changed), so it can spend two; its cheap check ({@link getIssuesEtagFieldsByResourceIdBatchResult}) spends
38
+ * nothing unless the credential is refused.
28
39
  *
29
40
  * Uncached on purpose: the caller owns caching, as with the git hosts' batch reads.
30
41
  */
@@ -54,6 +65,45 @@ var IssuesIntegration = class extends IntegrationBase {
54
65
  };
55
66
  }
56
67
  }
68
+ /**
69
+ * Result-returning wrapper for the cheap check behind the batch tracker issue read's etags: each target's change
70
+ * state ({@link IssueEtagFields}), in ONE call to {@link getProviderIssuesEtagFieldsByResourceId}, which is handed
71
+ * `options.etagIncludes` as the git hosts' check is. The slots mean
72
+ * what {@link getIssuesByResourceIdBatchResult}'s do — `fulfilled` with `undefined` is a PROVEN ABSENCE, `rejected`
73
+ * means that target could not be checked. Failures are judged and budgeted as in
74
+ * `GitHostIntegration.getIssuesEtagFieldsResult`: every slot comes back as it settled, even when none answered, and
75
+ * only a refused credential fails the call or spends a strike.
76
+ */
77
+ async getIssuesEtagFieldsByResourceIdBatchResult(targets, options, connectionId) {
78
+ const scope = getScopedLogger();
79
+ const session = await this.resolveReadSession(connectionId, scope);
80
+ if (session == null) return void 0;
81
+ const getProviderEtagFields = this.getProviderIssuesEtagFieldsByResourceId;
82
+ if (getProviderEtagFields == null) return { value: void 0 };
83
+ const start = performance.now();
84
+ try {
85
+ const slots = await getProviderEtagFields.call(this, session, targets, options);
86
+ if (slots == null) return {
87
+ value: void 0,
88
+ duration: performance.now() - start
89
+ };
90
+ const settled = await this.settleBatchRefusals(session, targets, slots, { keepOtherFailures: true });
91
+ if (slots.some((slot) => slot.status === "fulfilled")) this.resetRequestExceptionCount("getIssuesEtagFields");
92
+ return {
93
+ value: settled,
94
+ duration: performance.now() - start
95
+ };
96
+ } catch (ex) {
97
+ this.handleEtagCheckException("getIssuesEtagFields", ex, {
98
+ scope,
99
+ connectionId
100
+ });
101
+ return {
102
+ error: toError(ex),
103
+ duration: performance.now() - start
104
+ };
105
+ }
106
+ }
57
107
  async getAccountForResource(resource, connectionId) {
58
108
  return (await this.getAccountForResourceResult(resource, connectionId))?.value;
59
109
  }
@@ -1 +1 @@
1
- {"version":3,"file":"issuesIntegration.js","names":[],"sources":["../../../../../plus/integrations/src/models/issuesIntegration.ts"],"sourcesContent":["import type { Account } from '@gitlens/git/models/author.js';\nimport type { Issue, IssueShape } from '@gitlens/git/models/issue.js';\nimport type { ResourceDescriptor } from '@gitlens/git/models/resourceDescriptor.js';\nimport { gate } from '@gitlens/utils/decorators/gate.js';\nimport { trace } from '@gitlens/utils/decorators/log.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { mapSettledBounded } from '@gitlens/utils/promise.js';\nimport type { ProviderAuthenticationSession } from '../authentication/models.js';\nimport type { IntegrationIds } from '../constants.js';\nimport { providerFanOutConcurrency } from '../constants.js';\nimport { toError } from '../errors.js';\nimport type { ProviderApiCollectionResult } from '../providers/models.js';\nimport type { BatchSlot, Integration, IntegrationResult, IntegrationType } from './integration.js';\nimport { IntegrationBase } from './integration.js';\nimport type { IssuesForProjectOptions, ProjectIssuesDrain } from './issueReads.js';\n\nexport function isIssuesIntegration(integration: Integration): integration is IssuesIntegration {\n\treturn integration.type === 'issues';\n}\n\nexport abstract class IssuesIntegration<\n\tID extends IntegrationIds = IntegrationIds,\n\tT extends ResourceDescriptor = ResourceDescriptor,\n> extends IntegrationBase<ID> {\n\treadonly type: IntegrationType = 'issues';\n\n\tget supportsIssueLookupByResourceId(): boolean {\n\t\treturn this.getProviderIssueByResourceId != null;\n\t}\n\n\t/**\n\t * Result-returning wrapper for the BATCH tracker issue read: resolves several `(resourceId, identifier)` targets\n\t * with one {@link getProviderIssueByResourceId} request each, run with bounded concurrency. One settled slot per\n\t * input target: `fulfilled` with `undefined` means the issue does not exist or is not visible to this token;\n\t * `rejected` means that target could not be checked, never that it is absent.\n\t *\n\t * Failure isolation happens PER TARGET, mirroring `GitHostIntegration.getPullRequestsBatchResult`: the whole\n\t * call counts as a failure against the integration's request-exception budget only when EVERY slot rejected,\n\t * and not even then when a credential that checks out was refused by each target's own resource\n\t * (`settleBatchRefusals`), so a batch of mostly-good targets never spends more than one strike.\n\t *\n\t * Uncached on purpose: the caller owns caching, as with the git hosts' batch reads.\n\t */\n\tasync getIssuesByResourceIdBatchResult(\n\t\ttargets: readonly { resourceId: string; identifier: string; resourceUrl?: string }[],\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<BatchSlot<IssueShape | undefined>[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null) return undefined;\n\n\t\tconst getProviderIssue = this.getProviderIssueByResourceId;\n\t\tif (getProviderIssue == null) return { value: undefined };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst slots = await mapSettledBounded(targets, providerFanOutConcurrency, t =>\n\t\t\t\tgetProviderIssue.call(this, session, t.resourceId, t.identifier, t.resourceUrl),\n\t\t\t);\n\n\t\t\tconst settled = await this.settleBatchRefusals(session, targets, slots);\n\n\t\t\tthis.resetRequestExceptionCount('getIssue');\n\t\t\treturn { value: settled, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getIssue', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\tprotected getProviderIssueByResourceId?(\n\t\t_session: ProviderAuthenticationSession,\n\t\t_resourceId: string,\n\t\t_id: string,\n\t\t_resourceUrl: string | undefined,\n\t): Promise<Issue | undefined>;\n\n\t@trace()\n\tasync getAccountForResource(resource: T, connectionId?: string): Promise<Account | undefined> {\n\t\treturn (await this.getAccountForResourceResult(resource, connectionId))?.value;\n\t}\n\n\t/**\n\t * Result-returning core of {@link getAccountForResource}. Recovers a thrown error into `{ error }` so\n\t * callers can preserve its classification (e.g. a 401/403 → an `auth` warning that drives re-auth)\n\t * instead of collapsing every failure into an untyped `undefined`. Gated here (not on the wrapper) so\n\t * direct callers such as the ProviderBackend facade share the same dedup as `getAccountForResource`.\n\t */\n\t@gate()\n\tasync getAccountForResourceResult(\n\t\tresource: T,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<Account | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null) return undefined;\n\n\t\ttry {\n\t\t\tconst account = await this.getProviderAccountForResource(session, resource);\n\t\t\tthis.resetRequestExceptionCount('getAccountForResource');\n\t\t\treturn { value: account };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getAccountForResource', ex, { connectionId: connectionId });\n\t\t\treturn { error: toError(ex) };\n\t\t}\n\t}\n\n\tprotected abstract getProviderAccountForResource(\n\t\tsession: ProviderAuthenticationSession,\n\t\tresource: T,\n\t): Promise<Account | undefined>;\n\n\t@trace()\n\tasync getResourcesForUser(connectionId?: string): Promise<T[] | undefined> {\n\t\treturn (await this.getResourcesForUserResult(connectionId))?.value;\n\t}\n\n\t/**\n\t * Result-returning core of {@link getResourcesForUser}. Recovers thrown errors into `{ error }` so callers\n\t * can surface them as warnings rather than silently swallowing them to `undefined`. Gated here (not on the\n\t * wrapper) so direct callers such as the ProviderBackend facade share the same dedup as `getResourcesForUser`.\n\t */\n\t@gate()\n\tasync getResourcesForUserResult(connectionId?: string): Promise<IntegrationResult<T[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null) return undefined;\n\n\t\ttry {\n\t\t\tconst resources = await this.getProviderResourcesForUser(session);\n\t\t\tthis.resetRequestExceptionCount('getResourcesForUser');\n\t\t\treturn { value: resources };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getResourcesForUser', ex, { connectionId: connectionId });\n\t\t\treturn { error: toError(ex) };\n\t\t}\n\t}\n\n\tprotected abstract getProviderResourcesForUser(session: ProviderAuthenticationSession): Promise<T[] | undefined>;\n\n\t/**\n\t * Project discovery for a set of resources, returning the SDK collection `{ values, metadata }` (completeness\n\t * + per-resource failures) so callers can warn on failed resources and set `fetchFailed` without discarding\n\t * the resources that succeeded. Thrown errors are recovered into `{ error }` for the same reason: a caller\n\t * surfaces them as a warning rather than swallowing them to `undefined`.\n\t */\n\t@trace()\n\tasync getProjectsForResourcesWithMetadataResult(\n\t\tresources: T[],\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderApiCollectionResult<T> | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null) return undefined;\n\n\t\ttry {\n\t\t\tconst projects = await this.getProviderProjectsForResourcesWithMetadata(session, resources);\n\t\t\tawait this.confirmScopedAuthFailures(session, projects.metadata);\n\t\t\tthis.resetRequestExceptionCount('getProjectsForResources');\n\t\t\treturn { value: projects };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getProjectsForResources', ex, { connectionId: connectionId });\n\t\t\treturn { error: toError(ex) };\n\t\t}\n\t}\n\n\t/**\n\t * Metadata-aware provider project discovery. The default wraps the array-returning\n\t * {@link getProviderProjectsForResources} in `{ values }` with no metadata, so providers without a\n\t * fan-out completeness signal (Linear, Trello) need no change; Jira overrides it to preserve the SDK's\n\t * per-resource completeness/failures.\n\t */\n\tprotected async getProviderProjectsForResourcesWithMetadata(\n\t\tsession: ProviderAuthenticationSession,\n\t\tresources: T[],\n\t): Promise<ProviderApiCollectionResult<T>> {\n\t\tconst projects = await this.getProviderProjectsForResources(session, resources);\n\t\treturn { values: projects ?? [] };\n\t}\n\n\tprotected abstract getProviderProjectsForResources(\n\t\tsession: ProviderAuthenticationSession,\n\t\tresources: T[],\n\t): Promise<T[] | undefined>;\n\n\t@trace()\n\tasync getIssuesForProject(\n\t\tproject: T,\n\t\toptions?: IssuesForProjectOptions,\n\t\tconnectionId?: string,\n\t): Promise<IssueShape[] | undefined> {\n\t\treturn (await this.getIssuesForProjectResult(project, options, connectionId))?.value;\n\t}\n\n\t/**\n\t * Result-returning core of {@link getIssuesForProject}. Recovers thrown errors into `{ error }` so callers\n\t * (e.g. the ProviderBackend facade) can surface a per-provider warning instead of a silent empty read —\n\t * important for providers that throw on unsupported operations (e.g. Linear's not-implemented issue read).\n\t */\n\tasync getIssuesForProjectResult(\n\t\tproject: T,\n\t\toptions?: IssuesForProjectOptions,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<IssueShape[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null) return undefined;\n\n\t\ttry {\n\t\t\tconst issues = await this.getProviderIssuesForProject(session, project, options);\n\t\t\tthis.resetRequestExceptionCount('getIssuesForProject');\n\t\t\treturn { value: issues };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getIssuesForProject', ex, { connectionId: connectionId });\n\t\t\treturn { error: toError(ex) };\n\t\t}\n\t}\n\n\t/**\n\t * Truncation-aware variant of {@link getIssuesForProjectResult}. A provider that drains a project's issues\n\t * with an internal page backstop (Jira/Linear) overrides {@link getProviderIssuesForProjectWithTruncation}\n\t * to report when that backstop was hit, so the facade can surface an incomplete project read instead of\n\t * publishing it as complete. The default reports `truncated: false`.\n\t */\n\tasync getIssuesForProjectWithTruncationResult(\n\t\tproject: T,\n\t\toptions?: IssuesForProjectOptions,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProjectIssuesDrain | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null) return undefined;\n\n\t\ttry {\n\t\t\tconst result = await this.getProviderIssuesForProjectWithTruncation(session, project, options);\n\t\t\tawait this.confirmScopedAuthFailures(session, result?.metadata);\n\t\t\tthis.resetRequestExceptionCount('getIssuesForProject');\n\t\t\treturn { value: result };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getIssuesForProject', ex, { connectionId: connectionId });\n\t\t\treturn { error: toError(ex) };\n\t\t}\n\t}\n\n\tprotected abstract getProviderIssuesForProject(\n\t\tsession: ProviderAuthenticationSession,\n\t\tproject: T,\n\t\toptions?: IssuesForProjectOptions,\n\t): Promise<IssueShape[] | undefined>;\n\n\t/**\n\t * Truncation-aware core of {@link getProviderIssuesForProject}. The default wraps the plain read and\n\t * reports `truncated: false`; a provider whose per-project drain is capped by a page backstop overrides\n\t * this to report incompleteness. Optional metadata lets providers surface structured per-project failures\n\t * (e.g. a page-level auth rejection) without discarding the already-fetched prefix.\n\t */\n\tprotected async getProviderIssuesForProjectWithTruncation(\n\t\tsession: ProviderAuthenticationSession,\n\t\tproject: T,\n\t\toptions?: IssuesForProjectOptions,\n\t): Promise<ProjectIssuesDrain | undefined> {\n\t\tconst values = await this.getProviderIssuesForProject(session, project, options);\n\t\tif (values == null) return undefined;\n\t\treturn { values: values, truncated: false };\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"issuesIntegration.js","names":[],"sources":["../../../../../plus/integrations/src/models/issuesIntegration.ts"],"sourcesContent":["import type { Account } from '@gitlens/git/models/author.js';\nimport type { Issue, IssueShape } from '@gitlens/git/models/issue.js';\nimport type { ResourceDescriptor } from '@gitlens/git/models/resourceDescriptor.js';\nimport { gate } from '@gitlens/utils/decorators/gate.js';\nimport { trace } from '@gitlens/utils/decorators/log.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { mapSettledBounded } from '@gitlens/utils/promise.js';\nimport type { ProviderAuthenticationSession } from '../authentication/models.js';\nimport type { IntegrationIds } from '../constants.js';\nimport { providerFanOutConcurrency } from '../constants.js';\nimport { toError } from '../errors.js';\nimport type { ProviderApiCollectionResult } from '../providers/models.js';\nimport type {\n\tBatchSlot,\n\tIntegration,\n\tIntegrationResult,\n\tIntegrationType,\n\tIssueEtagFields,\n\tIssueEtagInclude,\n} from './integration.js';\nimport { IntegrationBase } from './integration.js';\nimport type { IssuesForProjectOptions, ProjectIssuesDrain } from './issueReads.js';\n\nexport function isIssuesIntegration(integration: Integration): integration is IssuesIntegration {\n\treturn integration.type === 'issues';\n}\n\nexport abstract class IssuesIntegration<\n\tID extends IntegrationIds = IntegrationIds,\n\tT extends ResourceDescriptor = ResourceDescriptor,\n> extends IntegrationBase<ID> {\n\treadonly type: IntegrationType = 'issues';\n\n\tget supportsIssueLookupByResourceId(): boolean {\n\t\treturn this.getProviderIssueByResourceId != null;\n\t}\n\n\t/**\n\t * Whether this tracker has the cheap check behind the batch issue read's etags\n\t * ({@link getProviderIssuesEtagFieldsByResourceId}). The read decides before calling anything, so a tracker without\n\t * one makes one call.\n\t */\n\tget supportsIssueEtagsByResourceId(): boolean {\n\t\treturn this.getProviderIssuesEtagFieldsByResourceId != null;\n\t}\n\n\t/**\n\t * Result-returning wrapper for the BATCH tracker issue read: resolves several `(resourceId, identifier)` targets\n\t * with one {@link getProviderIssueByResourceId} request each, run with bounded concurrency. One settled slot per\n\t * input target: `fulfilled` with `undefined` means the issue does not exist or is not visible to this token;\n\t * `rejected` means that target could not be checked, never that it is absent.\n\t *\n\t * Failure isolation happens PER TARGET, mirroring `GitHostIntegration.getPullRequestsBatchResult`: the whole\n\t * call counts as a failure against the integration's request-exception budget only when EVERY slot rejected,\n\t * and not even then when a credential that checks out was refused by each target's own resource\n\t * (`settleBatchRefusals`), so a batch of mostly-good targets never spends more than one strike. A batch read with\n\t * etags makes up to two such calls (a full read of the targets without an etag, and a full read of the ones that\n\t * changed), so it can spend two; its cheap check ({@link getIssuesEtagFieldsByResourceIdBatchResult}) spends\n\t * nothing unless the credential is refused.\n\t *\n\t * Uncached on purpose: the caller owns caching, as with the git hosts' batch reads.\n\t */\n\tasync getIssuesByResourceIdBatchResult(\n\t\ttargets: readonly { resourceId: string; identifier: string; resourceUrl?: string }[],\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<BatchSlot<IssueShape | undefined>[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null) return undefined;\n\n\t\tconst getProviderIssue = this.getProviderIssueByResourceId;\n\t\tif (getProviderIssue == null) return { value: undefined };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst slots = await mapSettledBounded(targets, providerFanOutConcurrency, t =>\n\t\t\t\tgetProviderIssue.call(this, session, t.resourceId, t.identifier, t.resourceUrl),\n\t\t\t);\n\n\t\t\tconst settled = await this.settleBatchRefusals(session, targets, slots);\n\n\t\t\tthis.resetRequestExceptionCount('getIssue');\n\t\t\treturn { value: settled, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getIssue', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\tprotected getProviderIssueByResourceId?(\n\t\t_session: ProviderAuthenticationSession,\n\t\t_resourceId: string,\n\t\t_id: string,\n\t\t_resourceUrl: string | undefined,\n\t): Promise<Issue | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the cheap check behind the batch tracker issue read's etags: each target's change\n\t * state ({@link IssueEtagFields}), in ONE call to {@link getProviderIssuesEtagFieldsByResourceId}, which is handed\n\t * `options.etagIncludes` as the git hosts' check is. The slots mean\n\t * what {@link getIssuesByResourceIdBatchResult}'s do — `fulfilled` with `undefined` is a PROVEN ABSENCE, `rejected`\n\t * means that target could not be checked. Failures are judged and budgeted as in\n\t * `GitHostIntegration.getIssuesEtagFieldsResult`: every slot comes back as it settled, even when none answered, and\n\t * only a refused credential fails the call or spends a strike.\n\t */\n\tasync getIssuesEtagFieldsByResourceIdBatchResult(\n\t\ttargets: readonly { resourceId: string; identifier: string; resourceUrl?: string }[],\n\t\toptions: { etagIncludes?: readonly IssueEtagInclude[] },\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<BatchSlot<IssueEtagFields | undefined>[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null) return undefined;\n\n\t\tconst getProviderEtagFields = this.getProviderIssuesEtagFieldsByResourceId;\n\t\tif (getProviderEtagFields == null) return { value: undefined };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst slots = await getProviderEtagFields.call(this, session, targets, options);\n\t\t\tif (slots == null) return { value: undefined, duration: performance.now() - start };\n\n\t\t\tconst settled = await this.settleBatchRefusals(session, targets, slots, { keepOtherFailures: true });\n\n\t\t\tif (slots.some(slot => slot.status === 'fulfilled')) {\n\t\t\t\tthis.resetRequestExceptionCount('getIssuesEtagFields');\n\t\t\t}\n\t\t\treturn { value: settled, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleEtagCheckException('getIssuesEtagFields', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL: the cheap check behind the batch tracker issue read's etags — one settled slot per input target, in\n\t * order, holding the issue's change state in the vocabulary {@link getProviderIssueByResourceId}'s issues end in,\n\t * so both reads compute the same etag. `fulfilled` with `undefined` is a PROVEN ABSENCE, as there; a tracker whose\n\t * cheap read can't prove one rejects the slot instead, so the full read decides. `undefined` declines the whole\n\t * check, sending every target to the full read without counting as a failure. A tracker implements this only\n\t * where it is cheaper than the full read. No tracker's row carries a real reaction count, so `'reactions'` in\n\t * `options.etagIncludes` reads nothing here.\n\t */\n\tprotected getProviderIssuesEtagFieldsByResourceId?(\n\t\tsession: ProviderAuthenticationSession,\n\t\ttargets: readonly { resourceId: string; identifier: string; resourceUrl?: string }[],\n\t\toptions: { etagIncludes?: readonly IssueEtagInclude[] },\n\t): Promise<PromiseSettledResult<IssueEtagFields | undefined>[] | undefined>;\n\n\t@trace()\n\tasync getAccountForResource(resource: T, connectionId?: string): Promise<Account | undefined> {\n\t\treturn (await this.getAccountForResourceResult(resource, connectionId))?.value;\n\t}\n\n\t/**\n\t * Result-returning core of {@link getAccountForResource}. Recovers a thrown error into `{ error }` so\n\t * callers can preserve its classification (e.g. a 401/403 → an `auth` warning that drives re-auth)\n\t * instead of collapsing every failure into an untyped `undefined`. Gated here (not on the wrapper) so\n\t * direct callers such as the ProviderBackend facade share the same dedup as `getAccountForResource`.\n\t */\n\t@gate()\n\tasync getAccountForResourceResult(\n\t\tresource: T,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<Account | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null) return undefined;\n\n\t\ttry {\n\t\t\tconst account = await this.getProviderAccountForResource(session, resource);\n\t\t\tthis.resetRequestExceptionCount('getAccountForResource');\n\t\t\treturn { value: account };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getAccountForResource', ex, { connectionId: connectionId });\n\t\t\treturn { error: toError(ex) };\n\t\t}\n\t}\n\n\tprotected abstract getProviderAccountForResource(\n\t\tsession: ProviderAuthenticationSession,\n\t\tresource: T,\n\t): Promise<Account | undefined>;\n\n\t@trace()\n\tasync getResourcesForUser(connectionId?: string): Promise<T[] | undefined> {\n\t\treturn (await this.getResourcesForUserResult(connectionId))?.value;\n\t}\n\n\t/**\n\t * Result-returning core of {@link getResourcesForUser}. Recovers thrown errors into `{ error }` so callers\n\t * can surface them as warnings rather than silently swallowing them to `undefined`. Gated here (not on the\n\t * wrapper) so direct callers such as the ProviderBackend facade share the same dedup as `getResourcesForUser`.\n\t */\n\t@gate()\n\tasync getResourcesForUserResult(connectionId?: string): Promise<IntegrationResult<T[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null) return undefined;\n\n\t\ttry {\n\t\t\tconst resources = await this.getProviderResourcesForUser(session);\n\t\t\tthis.resetRequestExceptionCount('getResourcesForUser');\n\t\t\treturn { value: resources };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getResourcesForUser', ex, { connectionId: connectionId });\n\t\t\treturn { error: toError(ex) };\n\t\t}\n\t}\n\n\tprotected abstract getProviderResourcesForUser(session: ProviderAuthenticationSession): Promise<T[] | undefined>;\n\n\t/**\n\t * Project discovery for a set of resources, returning the SDK collection `{ values, metadata }` (completeness\n\t * + per-resource failures) so callers can warn on failed resources and set `fetchFailed` without discarding\n\t * the resources that succeeded. Thrown errors are recovered into `{ error }` for the same reason: a caller\n\t * surfaces them as a warning rather than swallowing them to `undefined`.\n\t */\n\t@trace()\n\tasync getProjectsForResourcesWithMetadataResult(\n\t\tresources: T[],\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderApiCollectionResult<T> | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null) return undefined;\n\n\t\ttry {\n\t\t\tconst projects = await this.getProviderProjectsForResourcesWithMetadata(session, resources);\n\t\t\tawait this.confirmScopedAuthFailures(session, projects.metadata);\n\t\t\tthis.resetRequestExceptionCount('getProjectsForResources');\n\t\t\treturn { value: projects };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getProjectsForResources', ex, { connectionId: connectionId });\n\t\t\treturn { error: toError(ex) };\n\t\t}\n\t}\n\n\t/**\n\t * Metadata-aware provider project discovery. The default wraps the array-returning\n\t * {@link getProviderProjectsForResources} in `{ values }` with no metadata, so providers without a\n\t * fan-out completeness signal (Linear, Trello) need no change; Jira overrides it to preserve the SDK's\n\t * per-resource completeness/failures.\n\t */\n\tprotected async getProviderProjectsForResourcesWithMetadata(\n\t\tsession: ProviderAuthenticationSession,\n\t\tresources: T[],\n\t): Promise<ProviderApiCollectionResult<T>> {\n\t\tconst projects = await this.getProviderProjectsForResources(session, resources);\n\t\treturn { values: projects ?? [] };\n\t}\n\n\tprotected abstract getProviderProjectsForResources(\n\t\tsession: ProviderAuthenticationSession,\n\t\tresources: T[],\n\t): Promise<T[] | undefined>;\n\n\t@trace()\n\tasync getIssuesForProject(\n\t\tproject: T,\n\t\toptions?: IssuesForProjectOptions,\n\t\tconnectionId?: string,\n\t): Promise<IssueShape[] | undefined> {\n\t\treturn (await this.getIssuesForProjectResult(project, options, connectionId))?.value;\n\t}\n\n\t/**\n\t * Result-returning core of {@link getIssuesForProject}. Recovers thrown errors into `{ error }` so callers\n\t * (e.g. the ProviderBackend facade) can surface a per-provider warning instead of a silent empty read —\n\t * important for providers that throw on unsupported operations (e.g. Linear's not-implemented issue read).\n\t */\n\tasync getIssuesForProjectResult(\n\t\tproject: T,\n\t\toptions?: IssuesForProjectOptions,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<IssueShape[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null) return undefined;\n\n\t\ttry {\n\t\t\tconst issues = await this.getProviderIssuesForProject(session, project, options);\n\t\t\tthis.resetRequestExceptionCount('getIssuesForProject');\n\t\t\treturn { value: issues };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getIssuesForProject', ex, { connectionId: connectionId });\n\t\t\treturn { error: toError(ex) };\n\t\t}\n\t}\n\n\t/**\n\t * Truncation-aware variant of {@link getIssuesForProjectResult}. A provider that drains a project's issues\n\t * with an internal page backstop (Jira/Linear) overrides {@link getProviderIssuesForProjectWithTruncation}\n\t * to report when that backstop was hit, so the facade can surface an incomplete project read instead of\n\t * publishing it as complete. The default reports `truncated: false`.\n\t */\n\tasync getIssuesForProjectWithTruncationResult(\n\t\tproject: T,\n\t\toptions?: IssuesForProjectOptions,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProjectIssuesDrain | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null) return undefined;\n\n\t\ttry {\n\t\t\tconst result = await this.getProviderIssuesForProjectWithTruncation(session, project, options);\n\t\t\tawait this.confirmScopedAuthFailures(session, result?.metadata);\n\t\t\tthis.resetRequestExceptionCount('getIssuesForProject');\n\t\t\treturn { value: result };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getIssuesForProject', ex, { connectionId: connectionId });\n\t\t\treturn { error: toError(ex) };\n\t\t}\n\t}\n\n\tprotected abstract getProviderIssuesForProject(\n\t\tsession: ProviderAuthenticationSession,\n\t\tproject: T,\n\t\toptions?: IssuesForProjectOptions,\n\t): Promise<IssueShape[] | undefined>;\n\n\t/**\n\t * Truncation-aware core of {@link getProviderIssuesForProject}. The default wraps the plain read and\n\t * reports `truncated: false`; a provider whose per-project drain is capped by a page backstop overrides\n\t * this to report incompleteness. Optional metadata lets providers surface structured per-project failures\n\t * (e.g. a page-level auth rejection) without discarding the already-fetched prefix.\n\t */\n\tprotected async getProviderIssuesForProjectWithTruncation(\n\t\tsession: ProviderAuthenticationSession,\n\t\tproject: T,\n\t\toptions?: IssuesForProjectOptions,\n\t): Promise<ProjectIssuesDrain | undefined> {\n\t\tconst values = await this.getProviderIssuesForProject(session, project, options);\n\t\tif (values == null) return undefined;\n\t\treturn { values: values, truncated: false };\n\t}\n}\n"],"mappings":"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"}
@@ -207,7 +207,7 @@ var AzureDevOpsApi = class {
207
207
  const issueType = issueResult.fields["System.WorkItemType"];
208
208
  const state = issueResult.fields["System.State"];
209
209
  const stateCategory = await this.getWorkItemStateCategory(issueType, state, provider, token, project.resourceName, project.name, options);
210
- return fromAzureWorkItem(issueResult, provider, project, stateCategory);
210
+ return fromAzureWorkItem(issueResult, provider, project, stateCategory, "point");
211
211
  }
212
212
  } catch (ex) {
213
213
  if (ex instanceof AuthenticationError) throw ex;
@@ -399,7 +399,7 @@ var AzureDevOpsApi = class {
399
399
  const project = options.resolveProject(projectName);
400
400
  if (project == null) throw new Error(`Azure DevOps work item ${id} is in project '${projectName}', which isn't visible`);
401
401
  const stateCategory = await this.getWorkItemStateCategory(workItem.fields["System.WorkItemType"], workItem.fields["System.State"], provider, token, collection, project.name, options);
402
- values.push(fromAzureWorkItem(workItem, provider, project, stateCategory));
402
+ values.push(fromAzureWorkItem(workItem, provider, project, stateCategory, "search"));
403
403
  }
404
404
  }
405
405
  const nextOffset = offset + slice.length;
@@ -457,7 +457,7 @@ var AzureDevOpsApi = class {
457
457
  }
458
458
  async toPullRequest(pr, provider, token, owner, baseUrl, scope, cancellation) {
459
459
  const forkRepositoryUrls = await this.getForkRepositoryUrls(provider, token, owner, baseUrl, pr.forkSource?.repository, scope, cancellation);
460
- return fromAzurePullRequest(pr, provider, owner, baseUrl, forkRepositoryUrls);
460
+ return fromAzurePullRequest(pr, provider, owner, baseUrl, forkRepositoryUrls, "point");
461
461
  }
462
462
  /**
463
463
  * Resolves the web and HTTPS clone URLs of the fork a cross-repository pull request comes from. Every other