@gitkraken/core-gitlens 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -1
- package/dist/git-cli/exec/git.js +1 -1
- package/dist/git-cli/providers/config.js +2 -2
- package/dist/git-cli/providers/pausedOperations.js +2 -2
- package/dist/git-cli/providers/pausedOperations.js.map +1 -1
- package/dist/git-cli/providers/staging.js +1 -1
- package/dist/ipc/discovery.js +1 -1
- package/dist/plus/agents/providers/claudeCodeTranscript.js +6 -6
- package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -1
- package/dist/plus/ai/providers/openAICompatibleProviderBase.js +1 -1
- package/dist/plus/integrations/providers/azure/azure.js +1 -1
- package/dist/plus/integrations/providers/linear.d.ts +4 -4
- package/dist/plus/integrations/providers/linear.js +24 -7
- package/dist/plus/integrations/providers/linear.js.map +1 -1
- package/dist/plus/integrations/providers/models.js.map +1 -1
- package/dist/plus/integrations/providers/providersApi.d.ts +2 -0
- package/dist/plus/integrations/providers/providersApi.js.map +1 -1
- package/dist/plus/integrations/reads/issueTracker.d.ts +4 -1
- package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
- package/dist/utils/env/node/exec.js +2 -2
- package/docs/integrations.md +4 -1
- package/package.json +2 -2
|
@@ -10,7 +10,10 @@ export declare function listIssueTrackerIssuesPage(ctx: ProviderReadContext, opt
|
|
|
10
10
|
org?: string;
|
|
11
11
|
project?: string;
|
|
12
12
|
filters?: IssueFilter[];
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Broadens the read to every assignee. Scopes to the user's issues when omitted: those assigned to them, and on
|
|
15
|
+
* Linear also the GitHub-synced issues they created (unless `filters` asks for `Assignee` by name).
|
|
16
|
+
*/
|
|
14
17
|
includeAllAssignees?: boolean;
|
|
15
18
|
/**
|
|
16
19
|
* How to order the issues, as `field:direction`. Omitted orders most-recently-updated-first where the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issueTracker.js","names":[],"sources":["../../../../../plus/integrations/src/reads/issueTracker.ts"],"sourcesContent":["import type { CollectionMetadata, CollectionScope } from '@gitkraken/provider-apis';\nimport type { IssueShape, IssueSorting, IssueStateFilter } from '@gitlens/git/models/issue.js';\nimport type { ResourceDescriptor } from '@gitlens/git/models/resourceDescriptor.js';\nimport { mapBounded } from '@gitlens/utils/promise.js';\nimport { assessCollectionMetadata, mergeAssessmentInto } from '../collectionMetadata.js';\nimport type { IntegrationIds } from '../constants.js';\nimport { IssuesCloudHostIntegrationId, providerFanOutConcurrency } from '../constants.js';\nimport { toError } from '../errors.js';\nimport type { IntegrationResult } from '../models/integration.js';\nimport type { ProjectIssuesDrain, ProjectIssuesRecovery } from '../models/issueReads.js';\nimport { isIssuesIntegration } from '../models/issuesIntegration.js';\nimport type { LinearIntegration } from '../providers/linear.js';\nimport { IssueFilter, providersMetadata } from '../providers/models.js';\nimport { mergeCollectionMetadata, parsePageCursor } from '../providers/utils/providerPaging.js';\nimport type { ProviderPagedResult, ProviderWarning, ProviderWarningSelector } from '../results.js';\nimport { appendDedupedWarning, reconcileOmissionsWithFailure } from '../results.js';\nimport { isIssuesHostIntegrationId, isLinearIntegration } from '../utils/integration.utils.js';\nimport type { ProviderReadContext } from './context.js';\nimport { linearProjectIds, parseIssueTrackerPageCursor, toIssueTrackerPageCursor } from './cursors.js';\nimport { discoverResources, runCaptured } from './drains.js';\nimport { projectKey, resourceIdForProject, resourceLabel, selectorMatches } from './hierarchy.utils.js';\nimport { resolveIssueSort, toIssueOrdering } from './ordering.js';\nimport type { SelectionTarget, TrackerSelectorKind } from './selectionConfirmation.js';\nimport { confirmCredential, confirmSelection, toSelectionAction } from './selectionConfirmation.js';\nimport {\n\tincompleteReadWarning,\n\tissueTrackerOnlySurfaceWarning,\n\totherWarning,\n\tprojectCutWarning,\n\tunmatchedSelectorWarning,\n\tunmergeableIssueSortWarning,\n\tunsupportedIssueSortWarning,\n\tunsupportedWarning,\n} from './warnings.js';\n\nconst issueStateFilters: readonly IssueStateFilter[] = ['open', 'closed', 'all'];\n\nexport function listIssueTrackerIssuesPage(\n\tctx: ProviderReadContext,\n\toptions: {\n\t\tproviderId: IntegrationIds;\n\t\torg?: string;\n\t\tproject?: string;\n\t\tfilters?: IssueFilter[];\n\t\t/** Broadens the read to every assignee. Scopes to user-assigned issues when omitted. */\n\t\tincludeAllAssignees?: boolean;\n\t\t/**\n\t\t * How to order the issues, as `field:direction`. Omitted orders most-recently-updated-first where the\n\t\t * tracker can express it.\n\t\t *\n\t\t * Validated against `getSupportedFilters().issues`' sibling `issueSorts` — a tracker reports there, not\n\t\t * under the account-wide table, because resource -> project IS its only issue surface. A key it can't\n\t\t * express refuses the read rather than serving a differently-ordered list.\n\t\t *\n\t\t * One page can span SEVERAL projects, whose issues are merged here, so a key no normalized issue carries\n\t\t * (`priority`, `dueDate`, `resolved`) is refused for a multi-project page even though the tracker orders by\n\t\t * it perfectly well within one project.\n\t\t *\n\t\t * Unlike the git-host reads this one is safe to change mid-pagination: its cursor windows PROJECTS and\n\t\t * drains each to exhaustion, so which projects a round covers doesn't depend on how their issues are\n\t\t * ordered. Only the order within a page changes.\n\t\t */\n\t\tsort?: IssueSorting;\n\t\t/**\n\t\t * Which issue states to read. Omitted reads open issues only.\n\t\t *\n\t\t * Applied server-side by every project read, so it narrows each project's drain rather than the merged page.\n\t\t * Only a tracker declaring `ProviderMetadata.supportsIssueStates` can express anything but `'open'`; asking\n\t\t * another for `'closed'`/`'all'` refuses the read rather than serving its open issues.\n\t\t */\n\t\tstate?: IssueStateFilter;\n\t\t/**\n\t\t * Linear only: narrows the read to issues in any of these Linear Projects (Linear's `Project` entity, by id).\n\t\t *\n\t\t * A narrowing of each team's read, not a scope of its own: the read is still windowed and selected by team\n\t\t * (`org`/`project`), and each team reports the issues in these Projects, server-side, so they don't count\n\t\t * against its page backstop. A Linear Project spans teams, so a read of every team is what reads a Project\n\t\t * whole. Refused by every other tracker rather than ignored, since ignoring it would publish the whole project.\n\t\t * Recorded in a composite cursor and checked on resume, as `state` is.\n\t\t */\n\t\tlinearProjects?: string[];\n\t\tforceSync?: boolean;\n\t\tpage?: number;\n\t\tcursor?: string;\n\t\titemsPerPage?: number;\n\t\tconnectionId?: string;\n\t\t/**\n\t\t * Explicit self-managed tracker host. Used to select the instance when the requested connection has no\n\t\t * configured domain; it must come from the trusted authentication configuration, never from repository\n\t\t * or remote data. Ignored for the cloud trackers.\n\t\t */\n\t\tdomain?: string;\n\t},\n): Promise<ProviderPagedResult<IssueShape>> {\n\treturn readIssueTrackerIssuesPage(ctx, options, false);\n}\n\n/**\n * {@link listIssueTrackerIssuesPage}. `refreshed` marks the one read made again after a selection's confirmation\n * found the cached discovery stale and dropped it, so this read's discovery is fresh and no further one is made.\n */\nasync function readIssueTrackerIssuesPage(\n\tctx: ProviderReadContext,\n\toptions: Parameters<typeof listIssueTrackerIssuesPage>[1],\n\trefreshed: boolean,\n): Promise<ProviderPagedResult<IssueShape>> {\n\t// Pagination is opt-in: only window the projects when the caller actually asked to page. A caller that\n\t// passes none of page/cursor/itemsPerPage keeps the \"aggregate every matched project\" contract, so an\n\t// existing consumer that doesn't inspect `hasMore` never silently loses projects past a default window.\n\tconst compositeCursor = parseIssueTrackerPageCursor(options.cursor);\n\tconst paginated =\n\t\tcompositeCursor?.unpaged !== true &&\n\t\t(options.page != null || options.cursor != null || options.itemsPerPage != null);\n\t// A composite cursor can carry retries from earlier project windows alongside the next untouched window.\n\t// `currentPage` remains the caller-facing position; `nextPage` is the window this round should advance.\n\tconst page = Math.max(\n\t\t1,\n\t\tMath.trunc(compositeCursor?.currentPage ?? parsePageCursor(options.cursor) ?? options.page ?? 1),\n\t);\n\tconst projectsPerPage = Math.max(1, Math.trunc(options.itemsPerPage ?? 20));\n\tconst linearProjects = linearProjectIds(options.linearProjects);\n\n\tconst items: IssueShape[] = [];\n\tconst warnings: ProviderWarning[] = [];\n\tconst emptyPage = (\n\t\tfetchFailed?: boolean,\n\t\ttruncated?: boolean,\n\t\tretry?: {\n\t\t\tnextPage?: number;\n\t\t\tpages?: readonly number[];\n\t\t\tprojects?: readonly string[];\n\t\t\tcompletedProjects?: readonly string[];\n\t\t},\n\t): ProviderPagedResult<IssueShape> => {\n\t\tconst cursor =\n\t\t\tretry != null\n\t\t\t\t? toIssueTrackerPageCursor({\n\t\t\t\t\t\tcurrentPage: page + 1,\n\t\t\t\t\t\tunpaged: !paginated,\n\t\t\t\t\t\tnextPage: retry.nextPage,\n\t\t\t\t\t\tretryPages: retry.pages ?? [],\n\t\t\t\t\t\tretryProjects: retry.projects ?? [],\n\t\t\t\t\t\tcompletedProjects: retry.completedProjects ?? [],\n\t\t\t\t\t\tstate: options.state,\n\t\t\t\t\t\tlinearProjects: linearProjects,\n\t\t\t\t\t})\n\t\t\t\t: undefined;\n\t\treturn {\n\t\t\titems: items,\n\t\t\twarnings: warnings,\n\t\t\tpage: { currentPage: page, itemsPerPage: items.length, truncated: truncated || undefined },\n\t\t\t// Retry-only state is deliberately manual: advertising it as forward progress would make a\n\t\t\t// persistent provider failure spin forever in a normal `while (hasMore)` consumer. An untouched\n\t\t\t// project window remains normal forward progress even when this window failed completely.\n\t\t\thasMore: retry?.nextPage != null && cursor != null,\n\t\t\tcursor: cursor,\n\t\t\tfetchFailed: fetchFailed || undefined,\n\t\t};\n\t};\n\tconst normalWindowPage = paginated\n\t\t? (compositeCursor?.nextPage ?? (compositeCursor == null ? page : undefined))\n\t\t: undefined;\n\tconst priorRetryPages = compositeCursor?.retryPages ?? [];\n\tconst priorRetryProjects = compositeCursor?.retryProjects ?? [];\n\tconst priorCompletedProjects = compositeCursor?.completedProjects ?? [];\n\tconst trackCompletedProjects =\n\t\tpriorCompletedProjects.length > 0 || priorRetryPages.length > 0 || compositeCursor?.completedProjects != null;\n\tconst retryPagesForDiscoveryFailure = (): number[] => [\n\t\t...priorRetryPages,\n\t\t...(normalWindowPage != null ? [normalWindowPage] : compositeCursor == null ? [1] : []),\n\t];\n\tconst discoveryFailureRetry = (): {\n\t\tpages: readonly number[];\n\t\tprojects: readonly string[];\n\t\tcompletedProjects: readonly string[];\n\t} => ({\n\t\tpages: retryPagesForDiscoveryFailure(),\n\t\tprojects: priorRetryProjects,\n\t\tcompletedProjects: priorCompletedProjects,\n\t});\n\n\tif (!isIssuesHostIntegrationId(options.providerId)) {\n\t\twarnings.push(\n\t\t\tissueTrackerOnlySurfaceWarning(options.providerId, options.connectionId, 'Issue-tracker project reads'),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\tconst integration = await ctx.getIntegrationForRead(options.providerId, options.connectionId, options.domain);\n\tif (integration == null) {\n\t\t// A supplied connectionId or domain that no longer resolves is a broken target, not an empty account.\n\t\tconst early = ctx.earlyReturnConnectionWarnings(options.providerId, options.connectionId, options.domain);\n\t\twarnings.push(...early.warnings);\n\t\treturn emptyPage(early.fetchFailed);\n\t}\n\tif (!isIssuesIntegration(integration)) {\n\t\twarnings.push(\n\t\t\tissueTrackerOnlySurfaceWarning(options.providerId, options.connectionId, 'Issue-tracker project reads'),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\tconst domain = ctx.domainForRead(integration, options.providerId, options.connectionId, options.domain);\n\n\t// Before any upstream request: the discovery fan-outs below (resources, projects, per-resource accounts) are\n\t// three round trips, and an order this tracker can't express refuses the read whatever they return. Placed after\n\t// `domain` only because every warning carries it.\n\tconst resolvedSort = resolveIssueSort(providersMetadata[options.providerId]?.supportedIssueSorts, options.sort);\n\tif (resolvedSort.rejection != null) {\n\t\twarnings.push(\n\t\t\tunsupportedIssueSortWarning(options.providerId, domain, options.connectionId, resolvedSort.rejection),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\tconst sort = resolvedSort.sort;\n\n\t// Refused before any request for the same reason as the sort: a state the tracker can't express would otherwise\n\t// be dropped by its project reads, and their open issues published as the requested state. A value outside the\n\t// vocabulary is refused too, since `toProviderIssueStates` would read it as omitted, which means open.\n\tif (\n\t\toptions.state != null &&\n\t\t(!issueStateFilters.includes(options.state) ||\n\t\t\t(options.state !== 'open' && !providersMetadata[options.providerId]?.supportsIssueStates))\n\t) {\n\t\t// A known state this tracker can't express is an unsupported capability; a value outside the vocabulary is\n\t\t// caller input the caller fixes in the request.\n\t\twarnings.push(\n\t\t\tissueStateFilters.includes(options.state)\n\t\t\t\t? unsupportedWarning(\n\t\t\t\t\t\toptions.providerId,\n\t\t\t\t\t\tdomain,\n\t\t\t\t\t\toptions.connectionId,\n\t\t\t\t\t\t`Issue state '${options.state}' is not supported by '${options.providerId}'.`,\n\t\t\t\t\t)\n\t\t\t\t: otherWarning(\n\t\t\t\t\t\toptions.providerId,\n\t\t\t\t\t\tdomain,\n\t\t\t\t\t\toptions.connectionId,\n\t\t\t\t\t\t`Unknown issue state; expected one of ${issueStateFilters.join(', ')}.`,\n\t\t\t\t\t),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\t// A cursor resumed under another state than it was minted for skips what it already covered, whose other-state\n\t// issues were never read. A narrowed read only mints composite cursors, which record their state, so any other\n\t// cursor came from an open read.\n\tconst cursorState =\n\t\tcompositeCursor != null ? (compositeCursor.state ?? 'open') : options.cursor != null ? 'open' : undefined;\n\tif (cursorState != null && cursorState !== (options.state ?? 'open')) {\n\t\twarnings.push(\n\t\t\totherWarning(\n\t\t\t\toptions.providerId,\n\t\t\t\tdomain,\n\t\t\t\toptions.connectionId,\n\t\t\t\t'The cursor belongs to a read of another issue state; start again without it.',\n\t\t\t),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\t// Refused before any request like the state. A value that is not a list of non-empty ids is caller input, refused\n\t// rather than dropped, since dropping it (or its last entry) widens the read to every issue; another tracker would\n\t// ignore it and publish its whole project.\n\tif (options.linearProjects != null) {\n\t\tif (\n\t\t\t!Array.isArray(options.linearProjects) ||\n\t\t\toptions.linearProjects.some(id => typeof id !== 'string' || id.length === 0)\n\t\t) {\n\t\t\twarnings.push(\n\t\t\t\totherWarning(\n\t\t\t\t\toptions.providerId,\n\t\t\t\t\tdomain,\n\t\t\t\t\toptions.connectionId,\n\t\t\t\t\t'Linear Projects must be a list of non-empty ids.',\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn emptyPage(true);\n\t\t}\n\t\tif (options.linearProjects.length > 0 && options.providerId !== IssuesCloudHostIntegrationId.Linear) {\n\t\t\twarnings.push(\n\t\t\t\tunsupportedWarning(\n\t\t\t\t\toptions.providerId,\n\t\t\t\t\tdomain,\n\t\t\t\t\toptions.connectionId,\n\t\t\t\t\t`Narrowing by Linear Project is not supported by '${options.providerId}'.`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn emptyPage(true);\n\t\t}\n\t}\n\n\t// As with the state: a cursor resumed under other Projects skips teams drained under the ones it was minted for.\n\t// Only a composite cursor records them, so any other cursor came from a read narrowed to none.\n\tif (\n\t\toptions.cursor != null &&\n\t\t(compositeCursor?.linearProjects ?? []).join('\\0') !== (linearProjects ?? []).join('\\0')\n\t) {\n\t\twarnings.push(\n\t\t\totherWarning(\n\t\t\t\toptions.providerId,\n\t\t\t\tdomain,\n\t\t\t\toptions.connectionId,\n\t\t\t\t'The cursor belongs to a read of other Linear Projects; start again without it.',\n\t\t\t),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\tawait ctx.forceRefreshIfRequested(integration, options.forceSync, options.connectionId);\n\n\t// A Project id the workspace no longer lists narrows every team to nothing, which would read as a Project with no\n\t// issues. Reported as a selector miss instead, as an `org` or `project` that matches nothing is.\n\tif (linearProjects != null && isLinearIntegration(integration)) {\n\t\tconst missing = await findUnlistedLinearProject(integration, linearProjects, options.connectionId);\n\t\tif (missing != null) {\n\t\t\twarnings.push(\n\t\t\t\tunmatchedSelectorWarning(options.providerId, domain, options.connectionId, {\n\t\t\t\t\tkind: 'linearProject',\n\t\t\t\t\tvalue: missing,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\n\tawait integration.getCurrentAccount({ connectionId: options.connectionId }).catch(() => undefined);\n\n\tconst {\n\t\tvalue: resources,\n\t\twarning: resourcesWarning,\n\t\tmetadata: resourcesMetadata,\n\t} = await discoverResources(integration, options.providerId, domain, options.connectionId);\n\tif (resourcesWarning != null) {\n\t\twarnings.push(resourcesWarning);\n\t}\n\tconst scopedResources =\n\t\toptions.org != null\n\t\t\t? (resources ?? []).filter(r => selectorMatches(options.providerId, r, options.org!))\n\t\t\t: (resources ?? []);\n\t// Only a complete discovery proves a selection gone: a failed one may just not have reached it, and no resource\n\t// list without a warning is no session.\n\tconst resourceDiscoveryComplete = resources != null && resourcesWarning == null;\n\tconst selectionTarget: SelectionTarget = {\n\t\tintegration: integration,\n\t\tproviderId: options.providerId,\n\t\tdomain: domain,\n\t\tconnectionId: options.connectionId,\n\t\torg: options.org,\n\t\tproject: options.project,\n\t};\n\tconst unconfirmed = (reasons: readonly ProviderWarning[]): ProviderPagedResult<IssueShape> => {\n\t\tif (reasons.length === 0) {\n\t\t\twarnings.push(\n\t\t\t\totherWarning(\n\t\t\t\t\toptions.providerId,\n\t\t\t\t\tdomain,\n\t\t\t\t\toptions.connectionId,\n\t\t\t\t\t`Could not confirm '${options.project ?? options.org}' is gone, so it is not reported as removed.`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tfor (const warning of reasons) {\n\t\t\tappendDedupedWarning(warnings, warning);\n\t\t}\n\t\treturn emptyPage(true, false, discoveryFailureRetry());\n\t};\n\t/**\n\t * Settles a selection the cached discovery matches nothing for from the provider's lists as they are now (see\n\t * {@link confirmSelection} and {@link toSelectionAction}). The cached lists can predate what was created since, so\n\t * a stale one is dropped and the read made once more over fresh lists; that read confirms the same way, since its\n\t * own discovery can still be joined to one started before the drop.\n\t */\n\tconst missSelection = async (\n\t\tselector: ProviderWarningSelector & { kind: TrackerSelectorKind },\n\t): Promise<ProviderPagedResult<IssueShape>> => {\n\t\tconst next = toSelectionAction(await confirmSelection(selectionTarget, selector.kind), refreshed);\n\t\tswitch (next.action) {\n\t\t\tcase 'unconfirmed':\n\t\t\t\treturn unconfirmed(next.warnings);\n\t\t\tcase 'refresh':\n\t\t\t\tintegration.invalidateDiscoveryCaches();\n\t\t\t\t// The caches are dropped already: the refreshed read needs no second session sync.\n\t\t\t\treturn readIssueTrackerIssuesPage(ctx, { ...options, forceSync: false }, true);\n\t\t\tcase 'report-missing': {\n\t\t\t\tconst credential = await confirmCredential(selectionTarget, next.resource);\n\t\t\t\tif (!credential.confirmed) {\n\t\t\t\t\treturn unconfirmed(credential.warning != null ? [credential.warning] : []);\n\t\t\t\t}\n\n\t\t\t\t// What the lists miss now: a selected org that is gone misses the org, whichever the cache missed.\n\t\t\t\tconst missed: ProviderWarningSelector =\n\t\t\t\t\tnext.missed === 'org' && options.org != null ? { kind: 'org', value: options.org } : selector;\n\t\t\t\twarnings.push(\n\t\t\t\t\tunmatchedSelectorWarning(options.providerId, domain, options.connectionId, missed, options.org),\n\t\t\t\t);\n\t\t\t\treturn emptyPage();\n\t\t\t}\n\t\t}\n\t};\n\t// Checked before the empty return, since an account with no resources left misses the selection too.\n\tif (options.org != null && resourceDiscoveryComplete && scopedResources.length === 0) {\n\t\treturn missSelection({ kind: 'org', value: options.org });\n\t}\n\tif (resources == null || resources.length === 0) {\n\t\tif (options.project != null && resourceDiscoveryComplete) {\n\t\t\treturn missSelection({ kind: 'project', value: options.project });\n\t\t}\n\n\t\tconst fetchFailed = resourcesWarning != null && resources == null;\n\t\tconst { truncated } = mergeAssessmentInto(\n\t\t\twarnings,\n\t\t\toptions.providerId,\n\t\t\tdomain,\n\t\t\toptions.connectionId,\n\t\t\tresourcesMetadata,\n\t\t);\n\t\treturn emptyPage(fetchFailed, truncated, fetchFailed || truncated ? discoveryFailureRetry() : undefined);\n\t}\n\t// Only a partial discovery, reported by its warning, reaches here without the selected resource.\n\tif (scopedResources.length === 0) {\n\t\treturn emptyPage();\n\t}\n\n\tconst { value: projectsResult, warning: projectsWarning } = await runCaptured(\n\t\toptions.providerId,\n\t\tdomain,\n\t\toptions.connectionId,\n\t\t() => integration.getProjectsForResourcesWithMetadataResult(scopedResources, options.connectionId),\n\t);\n\tif (projectsWarning != null) {\n\t\twarnings.push(projectsWarning);\n\t}\n\t// Partial project discovery: continue with the resources that succeeded, but surface per-resource\n\t// failures as warnings and remember to mark the page fetchFailed so the caller knows some issues may be\n\t// missing. `projectDiscoveryFailed`/`projectDiscoveryTruncated` are OR-ed into the page's\n\t// fetchFailed/truncated at every return below (a truncated-but-not-failed discovery, e.g. a paging\n\t// backstop, still means the project set is incomplete).\n\tconst projectDiscoveryAssessment = mergeAssessmentInto(\n\t\twarnings,\n\t\toptions.providerId,\n\t\tdomain,\n\t\toptions.connectionId,\n\t\tprojectsResult?.metadata,\n\t);\n\tconst projectDiscoveryFailed = projectDiscoveryAssessment.fetchFailed;\n\tconst projectDiscoveryTruncated = projectDiscoveryAssessment.truncated;\n\tconst projects = projectsResult?.values;\n\tconst matchedProjects =\n\t\toptions.project != null\n\t\t\t? (projects ?? []).filter(p => selectorMatches(options.providerId, p, options.project!))\n\t\t\t: (projects ?? []);\n\tconst projectDiscoveryComplete =\n\t\tresourceDiscoveryComplete && projectsWarning == null && !projectDiscoveryFailed && !projectDiscoveryTruncated;\n\tif (options.project != null && projects != null && projectDiscoveryComplete && matchedProjects.length === 0) {\n\t\treturn missSelection({ kind: 'project', value: options.project });\n\t}\n\tif (projects == null || projects.length === 0) {\n\t\tconst fetchFailed = (projectsWarning != null && projectsResult == null) || projectDiscoveryFailed;\n\t\treturn emptyPage(\n\t\t\tfetchFailed,\n\t\t\tprojectDiscoveryTruncated,\n\t\t\tfetchFailed || projectDiscoveryTruncated ? discoveryFailureRetry() : undefined,\n\t\t);\n\t}\n\n\t// Validate the requested filters against what this provider supports (e.g. Linear/Trello support only\n\t// Assignee). An unsupported filter must not silently degrade — Linear/Trello ignore the requested type\n\t// and apply Assignee regardless — so warn + fetchFailed instead of returning a differently-scoped set.\n\tif (options.filters?.length) {\n\t\tconst supported = providersMetadata[options.providerId]?.supportedIssueFilters;\n\t\tconst allSupported = supported != null && options.filters.every(f => supported.includes(f));\n\t\tif (!allSupported) {\n\t\t\twarnings.push(\n\t\t\t\tunsupportedWarning(\n\t\t\t\t\toptions.providerId,\n\t\t\t\t\tdomain,\n\t\t\t\t\toptions.connectionId,\n\t\t\t\t\t`One or more requested issue filters are not supported by '${options.providerId}'.`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn emptyPage(true);\n\t\t}\n\t}\n\n\t// `includeAllAssignees` drops the user scope, but a user-relative filter (Author/Mention) is meaningless\n\t// without a user. Passing both to the provider degrades silently: Jira, seeing no user, falls through to\n\t// an unscoped project fetch and returns EVERY issue instead of the requested author's/mentions. Reject\n\t// the incompatible combination up front rather than publishing a differently-scoped set as the result.\n\tif (options.includeAllAssignees === true && options.filters?.some(f => f !== IssueFilter.Assignee)) {\n\t\twarnings.push(\n\t\t\tunsupportedWarning(\n\t\t\t\toptions.providerId,\n\t\t\t\tdomain,\n\t\t\t\toptions.connectionId,\n\t\t\t\t`\\`includeAllAssignees\\` cannot be combined with an author/mention filter for '${options.providerId}' (those filters require a user scope).`,\n\t\t\t),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\t// Scope to the current user's assigned issues unless the caller broadens to all assignees. Resolve the\n\t// handle from each resource's own account (multi-account safe), capturing any error so its kind\n\t// (e.g. auth) is preserved rather than collapsed to a generic warning.\n\tlet usersByResourceId: Map<string, string> | undefined;\n\t// The same accounts keyed by the same resource, holding the provider's stable id rather than the handle. A\n\t// separate map rather than a widened value because the two are resolved and consumed independently: a\n\t// provider may carry an account with no id, and `scopedProjectsWithUsers` gates on the HANDLE alone, so\n\t// folding them together would drop a resource whose id happened to be missing.\n\tlet userIdsByResourceId: Map<string, string> | undefined;\n\tlet accountLookupFailed = false;\n\tif (options.includeAllAssignees !== true) {\n\t\tusersByResourceId = new Map<string, string>();\n\t\tuserIdsByResourceId = new Map<string, string>();\n\t\tconst accounts = await mapBounded(scopedResources, providerFanOutConcurrency, async resource => ({\n\t\t\tresource: resource,\n\t\t\t...(await runCaptured(options.providerId, domain, options.connectionId, () =>\n\t\t\t\tintegration.getAccountForResourceResult(resource, options.connectionId),\n\t\t\t)),\n\t\t}));\n\n\t\tfor (const { resource, value: account, warning: accountWarning } of accounts) {\n\t\t\tconst user = account?.username ?? account?.name ?? undefined;\n\t\t\tif (user != null) {\n\t\t\t\tconst resourceKey = resourceIdForProject(resource) ?? resource.key;\n\t\t\t\tusersByResourceId.set(resourceKey, user);\n\t\t\t\t// Empty-checked, not just null-checked: an account shape declares `id` as a plain string, and a\n\t\t\t\t// provider with nothing to put there sets `''` rather than omitting it — which would otherwise\n\t\t\t\t// reach a user-field query as an empty identity and match nothing.\n\t\t\t\tif (account?.id != null && account.id !== '') {\n\t\t\t\t\tuserIdsByResourceId.set(resourceKey, account.id);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Deduped: a captured `accountWarning` carries only the provider error, with no resource in its\n\t\t\t// message, so one expired token across N resources would otherwise repeat verbatim N times. The\n\t\t\t// synthesized fallback names the resource, so those stay distinct on their own.\n\t\t\tappendDedupedWarning(\n\t\t\t\twarnings,\n\t\t\t\taccountWarning ??\n\t\t\t\t\totherWarning(\n\t\t\t\t\t\toptions.providerId,\n\t\t\t\t\t\tdomain,\n\t\t\t\t\t\toptions.connectionId,\n\t\t\t\t\t\t`Could not resolve the current user for '${resourceLabel(resource)}'; skipping that resource to avoid returning issues assigned to others.`,\n\t\t\t\t\t),\n\t\t\t);\n\t\t\taccountLookupFailed = true;\n\t\t}\n\t}\n\n\tconst fallbackUserForUnscopedProject =\n\t\tscopedResources.length === 1 && usersByResourceId?.size === 1\n\t\t\t? usersByResourceId.values().next().value\n\t\t\t: undefined;\n\tconst userForProject = (project: ResourceDescriptor): string | undefined => {\n\t\tconst resourceId = resourceIdForProject(project);\n\t\tif (resourceId != null) {\n\t\t\tconst user = usersByResourceId?.get(resourceId);\n\t\t\tif (user != null) {\n\t\t\t\treturn user;\n\t\t\t}\n\t\t}\n\n\t\t// Some providers/tests return project descriptors without their parent resource id. When we have only\n\t\t// one scoped resource, re-use that sole resolved user rather than silently dropping every project.\n\t\treturn fallbackUserForUnscopedProject;\n\t};\n\t// Deliberately NOT falling back the way `userForProject` does. That fallback exists so a project with no\n\t// parent resource id still gets scoped rather than dropped, and the handle is what the drop is judged on;\n\t// the id is optional everywhere it is read, so a miss degrades to the handle instead of widening the read.\n\tconst userIdForProject = (project: ResourceDescriptor): string | undefined => {\n\t\tconst resourceId = resourceIdForProject(project);\n\t\treturn resourceId != null ? userIdsByResourceId?.get(resourceId) : undefined;\n\t};\n\n\tconst retryProjectKeys = new Set<string>();\n\tconst completedProjectKeys = new Set(priorCompletedProjects);\n\tfor (const retryProject of priorRetryProjects) {\n\t\tcompletedProjectKeys.delete(retryProject);\n\t}\n\tconst scopedProjectsWithUsers =\n\t\tusersByResourceId != null\n\t\t\t? matchedProjects.filter(project => {\n\t\t\t\t\tif (userForProject(project) != null) return true;\n\n\t\t\t\t\tconst key = projectKey(project);\n\t\t\t\t\tretryProjectKeys.add(key);\n\t\t\t\t\tcompletedProjectKeys.delete(key);\n\t\t\t\t\treturn false;\n\t\t\t\t})\n\t\t\t: matchedProjects;\n\n\t// Select the untouched window plus any earlier windows/projects that explicitly need retrying. Keys\n\t// include the parent resource so two trackers can reuse the same project id without collapsing.\n\tconst projectsByRetryKey = new Map(scopedProjectsWithUsers.map(project => [projectKey(project), project]));\n\tconst scopedProjectsByKey = new Map<string, ResourceDescriptor>();\n\tconst addScopedProject = (project: ResourceDescriptor): void => {\n\t\tconst key = projectKey(project);\n\t\tif (completedProjectKeys.has(key)) return;\n\n\t\tscopedProjectsByKey.set(key, project);\n\t};\n\tfor (const retryProject of priorRetryProjects) {\n\t\tconst project = projectsByRetryKey.get(retryProject);\n\t\tif (project != null) {\n\t\t\taddScopedProject(project);\n\t\t} else if (projectDiscoveryFailed || projectDiscoveryTruncated) {\n\t\t\tretryProjectKeys.add(retryProject);\n\t\t}\n\t}\n\tconst windowPages = new Set<number>(priorRetryPages);\n\tif (normalWindowPage != null) {\n\t\twindowPages.add(normalWindowPage);\n\t}\n\tif (!paginated && (projectDiscoveryFailed || projectDiscoveryTruncated)) {\n\t\twindowPages.add(1);\n\t}\n\tif (paginated) {\n\t\tfor (const windowPage of windowPages) {\n\t\t\tconst windowStart = (windowPage - 1) * projectsPerPage;\n\t\t\tfor (const project of scopedProjectsWithUsers.slice(windowStart, windowStart + projectsPerPage)) {\n\t\t\t\taddScopedProject(project);\n\t\t\t}\n\t\t}\n\t} else if (compositeCursor == null || priorRetryPages.length > 0) {\n\t\t// An unpaged retry-only cursor should re-read only the explicitly failed projects already added\n\t\t// above. Discovery retries still rescan the aggregate set so newly recovered projects are included.\n\t\tfor (const project of scopedProjectsWithUsers) {\n\t\t\taddScopedProject(project);\n\t\t}\n\t}\n\tconst scopedProjects = [...scopedProjectsByKey.values()];\n\tconst furthestWindowPage = windowPages.size > 0 ? Math.max(...windowPages) : normalWindowPage;\n\tconst normalWindowEnd =\n\t\tfurthestWindowPage != null ? furthestWindowPage * projectsPerPage : scopedProjectsWithUsers.length;\n\tconst nextPage =\n\t\tpaginated && furthestWindowPage != null && scopedProjectsWithUsers.length > normalWindowEnd\n\t\t\t? furthestWindowPage + 1\n\t\t\t: undefined;\n\tconst retryWindowPages = (): number[] => {\n\t\tif (!projectDiscoveryFailed && !projectDiscoveryTruncated && retryProjectKeys.size === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst pages = new Set(windowPages);\n\t\tif (pages.size === 0) {\n\t\t\t// A terminal retry has no untouched next window to identify its origin. Keep a manual window\n\t\t\t// marker so a later partial discovery can reconcile against the projects already emitted.\n\t\t\tpages.add(paginated ? Math.max(1, page - 1) : 1);\n\t\t}\n\t\treturn [...pages];\n\t};\n\tif (scopedProjects.length === 0) {\n\t\t// The discovered projects didn't intersect the requested filter/window, or every matching resource\n\t\t// failed user resolution. If discovery or account lookup was partial, the empty result is not a\n\t\t// proven-empty account — carry `fetchFailed` so the caller knows issues may be missing.\n\t\treturn emptyPage(projectDiscoveryFailed || accountLookupFailed, projectDiscoveryTruncated, {\n\t\t\tnextPage: nextPage,\n\t\t\tpages: retryWindowPages(),\n\t\t\tprojects: [...retryProjectKeys],\n\t\t\tcompletedProjects: [...completedProjectKeys],\n\t\t});\n\t}\n\n\t// A read spanning several projects is a merge, so it can only honor a key a normalized issue carries. Bound here\n\t// rather than next to the key's validation above, because the project count is only known now — while still\n\t// before any project read, so a refusal costs no request. Refused rather than served as concatenated\n\t// per-project runs, which would look ordered without being so.\n\t//\n\t// Counted over every project the READ covers, not the `scopedProjects` window this page happens to hold: the\n\t// window is `itemsPerPage` projects wide, so counting it would refuse a 20-project page and then serve the\n\t// final 1-project page of the same paginated call — the same key answered two ways, with the earlier pages'\n\t// issues missing from a read that reported success.\n\t//\n\t// Projects are not the only thing a tracker read merges: a user-scoped read asking for several relationships\n\t// issues one provider query PER relationship and unions them within each project (Jira runs one JQL drain per\n\t// filter and folds them into one map, in filter order), so a single-project page of two filters is just as\n\t// concatenated as a two-project one. Counting only projects published those runs under the requested key.\n\t// Not gated on the provider: the two trackers that don't fan out (Linear, Trello) declare `Assignee` as their\n\t// only supported filter, so a multi-filter read is already refused above and can never reach this.\n\tconst mergesFilters = options.includeAllAssignees !== true && (options.filters?.length ?? 0) > 1;\n\tconst ordering = toIssueOrdering(sort, scopedProjectsWithUsers.length > 1 || mergesFilters);\n\tif (ordering.unmergeable != null) {\n\t\twarnings.push(\n\t\t\tunmergeableIssueSortWarning(\n\t\t\t\toptions.providerId,\n\t\t\t\tdomain,\n\t\t\t\toptions.connectionId,\n\t\t\t\tordering.unmergeable,\n\t\t\t\tscopedProjectsWithUsers.length > 1 ? 'projects' : 'filters',\n\t\t\t),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\t// One call for the whole window, so a tracker that can search several projects at once (Jira) does, instead\n\t// of paying one drain per project. Results still come back per project, which the accounting below needs.\n\tlet projectReads: IntegrationResult<ProjectIssuesDrain | undefined>[];\n\ttry {\n\t\tprojectReads = await integration.getIssuesForProjectsWithTruncationResult(\n\t\t\tscopedProjects.map(project => ({\n\t\t\t\tproject: project,\n\t\t\t\toptions: {\n\t\t\t\t\tuser: userForProject(project),\n\t\t\t\t\tuserId: userIdForProject(project),\n\t\t\t\t\tfilters: options.filters,\n\t\t\t\t\tsort: sort,\n\t\t\t\t\tstate: options.state,\n\t\t\t\t\t...(linearProjects != null ? { linearProjects: linearProjects } : {}),\n\t\t\t\t},\n\t\t\t})),\n\t\t\toptions.connectionId,\n\t\t);\n\t} catch (ex) {\n\t\tconst error = toError(ex);\n\t\tprojectReads = scopedProjects.map(() => ({ error: error }));\n\t}\n\tconst perProject = await Promise.all(\n\t\tscopedProjects.map(async (project, index) => ({\n\t\t\tproject: project,\n\t\t\t...(await runCaptured(options.providerId, domain, options.connectionId, () =>\n\t\t\t\tPromise.resolve(projectReads[index]),\n\t\t\t)),\n\t\t})),\n\t);\n\t// Partial project discovery means some projects' issues are missing from this page; propagate it so the\n\t// page reports fetchFailed even when every discovered project's own read succeeded.\n\tlet fetchFailed = projectDiscoveryFailed || accountLookupFailed;\n\t// Whether a request failed, which `fetchFailed` alone doesn't say: see `assessCollectionMetadata`'s `requestFailed`.\n\tlet requestFailed = fetchFailed;\n\tlet truncated = projectDiscoveryTruncated;\n\t// The projects whose read stopped short with nothing in its metadata to say why. One whose provider names its scope\n\t// is reported on its own, even when the read also failed: a project's cut must not hide behind another's failure,\n\t// which may be no more than an issue it skipped (#6011), nor its recovery behind another project's.\n\tconst cuts: { project: ResourceDescriptor; recovery: ProjectIssuesRecovery; scope: CollectionScope }[] = [];\n\tlet drainMetadata: CollectionMetadata | undefined;\n\tfor (const { project, value: result, warning } of perProject) {\n\t\tconst key = projectKey(project);\n\t\tconst retryProject = result == null;\n\t\tif (warning != null) {\n\t\t\t// Deduped: the per-project warning is built from the provider error alone and names no project, so a\n\t\t\t// single failing token repeats verbatim once per project in the window.\n\t\t\tappendDedupedWarning(warnings, warning);\n\t\t\tfetchFailed = true;\n\t\t\trequestFailed = true;\n\t\t\ttruncated = true;\n\t\t}\n\t\t// A thrown/unsupported read (e.g. Linear not-implemented) surfaces as a warning with no value;\n\t\t// mark the aggregate as fetchFailed so an empty result isn't mistaken for \"no issues\".\n\t\tif (result == null) {\n\t\t\tfetchFailed = true;\n\t\t\trequestFailed = true;\n\t\t}\n\t\tif (result != null) {\n\t\t\titems.push(...result.values);\n\t\t\tif (result.truncated) {\n\t\t\t\ttruncated = true;\n\t\t\t\tif (result.scope != null && !result.metadata?.failures?.length && !result.metadata?.omissions?.length) {\n\t\t\t\t\tcuts.push({ project: project, recovery: result.recovery, scope: result.scope });\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (result.metadata != null) {\n\t\t\t\tdrainMetadata = mergeCollectionMetadata(drainMetadata, result.metadata);\n\t\t\t}\n\t\t}\n\t\tif (retryProject) {\n\t\t\tretryProjectKeys.add(key);\n\t\t\tcompletedProjectKeys.delete(key);\n\t\t} else {\n\t\t\t// A usable partial/truncated project is emitted once and remains structurally incomplete.\n\t\t\t// Re-running the same project cursor would normally return the same prefix and duplicate it\n\t\t\t// across facade pages; only a project that returned no value is safe to retry automatically.\n\t\t\tcompletedProjectKeys.add(key);\n\t\t}\n\t}\n\n\t// Each provider query arrived ordered by the tracker; the union of them — across projects, and across the\n\t// per-relationship queries a multi-filter read fans out into — is not, and the union is what this read\n\t// publishes. A no-op when nothing merged, since the tracker already ordered that single run.\n\tconst orderedItems = ordering.order(items);\n\n\tconst drainAssessment = assessCollectionMetadata(options.providerId, domain, options.connectionId, drainMetadata);\n\tfor (const warning of drainAssessment.warnings) {\n\t\t// The truncation the projects reported already gets a structured warning below. Replace metadata's unstructured\n\t\t// fallback, the only warning it raises when nothing failed and nothing was omitted, while retaining failures and\n\t\t// omissions.\n\t\tif (truncated && !drainAssessment.fetchFailed && warning.omission == null) continue;\n\n\t\tappendDedupedWarning(warnings, warning);\n\t}\n\tfetchFailed = fetchFailed || drainAssessment.fetchFailed;\n\trequestFailed = requestFailed || drainAssessment.requestFailed;\n\ttruncated = truncated || drainAssessment.truncated;\n\n\tfor (const { project, recovery, scope } of cuts) {\n\t\tappendDedupedWarning(\n\t\t\twarnings,\n\t\t\tprojectCutWarning(\n\t\t\t\toptions.providerId,\n\t\t\t\tdomain,\n\t\t\t\toptions.connectionId,\n\t\t\t\tresourceLabel(project),\n\t\t\t\trecovery,\n\t\t\t\tscope,\n\t\t\t),\n\t\t);\n\t}\n\t// A truncation no project's own warning accounts for (a project list read short, or a cut from a provider that names\n\t// no scope for its projects) is reported for the read as a whole, unless a failure or an omission explains it. On\n\t// `fetchFailed`, not `requestFailed`: an issue left unread truncates the read too, and its own warning explains that.\n\t// A project list read short publishes its own warning, so it is never left to an unreadable issue's alone.\n\tif (!fetchFailed && truncated && !warnings.some(warning => warning.omission != null)) {\n\t\tappendDedupedWarning(\n\t\t\twarnings,\n\t\t\tincompleteReadWarning(\n\t\t\t\toptions.providerId,\n\t\t\t\tdomain,\n\t\t\t\toptions.connectionId,\n\t\t\t\t'Some issues were omitted; the provider returned an incomplete result.',\n\t\t\t\t'exhausted',\n\t\t\t),\n\t\t);\n\t}\n\t// A metadata omission from an earlier project asserts the read succeeded; a later one may since have failed.\n\treconcileOmissionsWithFailure(warnings, requestFailed);\n\n\tconst retryPages = retryWindowPages();\n\tconst cursor = toIssueTrackerPageCursor({\n\t\tcurrentPage: page + 1,\n\t\tunpaged: !paginated,\n\t\tnextPage: nextPage,\n\t\tretryPages: retryPages,\n\t\tretryProjects: [...retryProjectKeys],\n\t\tcompletedProjects:\n\t\t\t(trackCompletedProjects ||\n\t\t\t\tprojectDiscoveryFailed ||\n\t\t\t\tprojectDiscoveryTruncated ||\n\t\t\t\tretryProjectKeys.size > 0) &&\n\t\t\t(retryPages.length > 0 || nextPage != null)\n\t\t\t\t? [...completedProjectKeys]\n\t\t\t\t: [],\n\t\tstate: options.state,\n\t\tlinearProjects: linearProjects,\n\t});\n\treturn {\n\t\titems: orderedItems,\n\t\twarnings: warnings,\n\t\tpage: { currentPage: page, itemsPerPage: orderedItems.length, truncated: truncated || undefined },\n\t\t// Failed-project retries alone are manual. Only an untouched project window is automatic progress.\n\t\thasMore: nextPage != null && cursor != null,\n\t\tcursor: cursor,\n\t\tfetchFailed: fetchFailed || undefined,\n\t\trequestFailed: requestFailed,\n\t\tunexpectedGap: nextPage != null && cursor == null,\n\t};\n}\n\n/**\n * The first of `ids` the workspace's Projects don't list, confirmed against a list read past the cache, since a cached\n * one can predate a Project created since. Undefined when every id is listed, or when no complete list can prove one\n * missing: the read then goes ahead, and an id that names nothing reads as empty.\n */\nasync function findUnlistedLinearProject(\n\tintegration: LinearIntegration,\n\tids: readonly string[],\n\tconnectionId: string | undefined,\n): Promise<string | undefined> {\n\tlet unlisted: string | undefined;\n\tfor (const fresh of [false, true]) {\n\t\tconst projects = (await integration.getWorkspaceProjectsResult(connectionId, { fresh: fresh }))?.value;\n\t\tif (\n\t\t\tprojects == null ||\n\t\t\tprojects.truncated === true ||\n\t\t\t(projects.metadata != null && projects.metadata.completeness !== 'complete')\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst listed = new Set(projects.values.map(project => project.id));\n\t\tunlisted = ids.find(id => !listed.has(id));\n\t\tif (unlisted == null) return undefined;\n\t}\n\treturn unlisted;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"issueTracker.js","names":[],"sources":["../../../../../plus/integrations/src/reads/issueTracker.ts"],"sourcesContent":["import type { CollectionMetadata, CollectionScope } from '@gitkraken/provider-apis';\nimport type { IssueShape, IssueSorting, IssueStateFilter } from '@gitlens/git/models/issue.js';\nimport type { ResourceDescriptor } from '@gitlens/git/models/resourceDescriptor.js';\nimport { mapBounded } from '@gitlens/utils/promise.js';\nimport { assessCollectionMetadata, mergeAssessmentInto } from '../collectionMetadata.js';\nimport type { IntegrationIds } from '../constants.js';\nimport { IssuesCloudHostIntegrationId, providerFanOutConcurrency } from '../constants.js';\nimport { toError } from '../errors.js';\nimport type { IntegrationResult } from '../models/integration.js';\nimport type { ProjectIssuesDrain, ProjectIssuesRecovery } from '../models/issueReads.js';\nimport { isIssuesIntegration } from '../models/issuesIntegration.js';\nimport type { LinearIntegration } from '../providers/linear.js';\nimport { IssueFilter, providersMetadata } from '../providers/models.js';\nimport { mergeCollectionMetadata, parsePageCursor } from '../providers/utils/providerPaging.js';\nimport type { ProviderPagedResult, ProviderWarning, ProviderWarningSelector } from '../results.js';\nimport { appendDedupedWarning, reconcileOmissionsWithFailure } from '../results.js';\nimport { isIssuesHostIntegrationId, isLinearIntegration } from '../utils/integration.utils.js';\nimport type { ProviderReadContext } from './context.js';\nimport { linearProjectIds, parseIssueTrackerPageCursor, toIssueTrackerPageCursor } from './cursors.js';\nimport { discoverResources, runCaptured } from './drains.js';\nimport { projectKey, resourceIdForProject, resourceLabel, selectorMatches } from './hierarchy.utils.js';\nimport { resolveIssueSort, toIssueOrdering } from './ordering.js';\nimport type { SelectionTarget, TrackerSelectorKind } from './selectionConfirmation.js';\nimport { confirmCredential, confirmSelection, toSelectionAction } from './selectionConfirmation.js';\nimport {\n\tincompleteReadWarning,\n\tissueTrackerOnlySurfaceWarning,\n\totherWarning,\n\tprojectCutWarning,\n\tunmatchedSelectorWarning,\n\tunmergeableIssueSortWarning,\n\tunsupportedIssueSortWarning,\n\tunsupportedWarning,\n} from './warnings.js';\n\nconst issueStateFilters: readonly IssueStateFilter[] = ['open', 'closed', 'all'];\n\nexport function listIssueTrackerIssuesPage(\n\tctx: ProviderReadContext,\n\toptions: {\n\t\tproviderId: IntegrationIds;\n\t\torg?: string;\n\t\tproject?: string;\n\t\tfilters?: IssueFilter[];\n\t\t/**\n\t\t * Broadens the read to every assignee. Scopes to the user's issues when omitted: those assigned to them, and on\n\t\t * Linear also the GitHub-synced issues they created (unless `filters` asks for `Assignee` by name).\n\t\t */\n\t\tincludeAllAssignees?: boolean;\n\t\t/**\n\t\t * How to order the issues, as `field:direction`. Omitted orders most-recently-updated-first where the\n\t\t * tracker can express it.\n\t\t *\n\t\t * Validated against `getSupportedFilters().issues`' sibling `issueSorts` — a tracker reports there, not\n\t\t * under the account-wide table, because resource -> project IS its only issue surface. A key it can't\n\t\t * express refuses the read rather than serving a differently-ordered list.\n\t\t *\n\t\t * One page can span SEVERAL projects, whose issues are merged here, so a key no normalized issue carries\n\t\t * (`priority`, `dueDate`, `resolved`) is refused for a multi-project page even though the tracker orders by\n\t\t * it perfectly well within one project.\n\t\t *\n\t\t * Unlike the git-host reads this one is safe to change mid-pagination: its cursor windows PROJECTS and\n\t\t * drains each to exhaustion, so which projects a round covers doesn't depend on how their issues are\n\t\t * ordered. Only the order within a page changes.\n\t\t */\n\t\tsort?: IssueSorting;\n\t\t/**\n\t\t * Which issue states to read. Omitted reads open issues only.\n\t\t *\n\t\t * Applied server-side by every project read, so it narrows each project's drain rather than the merged page.\n\t\t * Only a tracker declaring `ProviderMetadata.supportsIssueStates` can express anything but `'open'`; asking\n\t\t * another for `'closed'`/`'all'` refuses the read rather than serving its open issues.\n\t\t */\n\t\tstate?: IssueStateFilter;\n\t\t/**\n\t\t * Linear only: narrows the read to issues in any of these Linear Projects (Linear's `Project` entity, by id).\n\t\t *\n\t\t * A narrowing of each team's read, not a scope of its own: the read is still windowed and selected by team\n\t\t * (`org`/`project`), and each team reports the issues in these Projects, server-side, so they don't count\n\t\t * against its page backstop. A Linear Project spans teams, so a read of every team is what reads a Project\n\t\t * whole. Refused by every other tracker rather than ignored, since ignoring it would publish the whole project.\n\t\t * Recorded in a composite cursor and checked on resume, as `state` is.\n\t\t */\n\t\tlinearProjects?: string[];\n\t\tforceSync?: boolean;\n\t\tpage?: number;\n\t\tcursor?: string;\n\t\titemsPerPage?: number;\n\t\tconnectionId?: string;\n\t\t/**\n\t\t * Explicit self-managed tracker host. Used to select the instance when the requested connection has no\n\t\t * configured domain; it must come from the trusted authentication configuration, never from repository\n\t\t * or remote data. Ignored for the cloud trackers.\n\t\t */\n\t\tdomain?: string;\n\t},\n): Promise<ProviderPagedResult<IssueShape>> {\n\treturn readIssueTrackerIssuesPage(ctx, options, false);\n}\n\n/**\n * {@link listIssueTrackerIssuesPage}. `refreshed` marks the one read made again after a selection's confirmation\n * found the cached discovery stale and dropped it, so this read's discovery is fresh and no further one is made.\n */\nasync function readIssueTrackerIssuesPage(\n\tctx: ProviderReadContext,\n\toptions: Parameters<typeof listIssueTrackerIssuesPage>[1],\n\trefreshed: boolean,\n): Promise<ProviderPagedResult<IssueShape>> {\n\t// Pagination is opt-in: only window the projects when the caller actually asked to page. A caller that\n\t// passes none of page/cursor/itemsPerPage keeps the \"aggregate every matched project\" contract, so an\n\t// existing consumer that doesn't inspect `hasMore` never silently loses projects past a default window.\n\tconst compositeCursor = parseIssueTrackerPageCursor(options.cursor);\n\tconst paginated =\n\t\tcompositeCursor?.unpaged !== true &&\n\t\t(options.page != null || options.cursor != null || options.itemsPerPage != null);\n\t// A composite cursor can carry retries from earlier project windows alongside the next untouched window.\n\t// `currentPage` remains the caller-facing position; `nextPage` is the window this round should advance.\n\tconst page = Math.max(\n\t\t1,\n\t\tMath.trunc(compositeCursor?.currentPage ?? parsePageCursor(options.cursor) ?? options.page ?? 1),\n\t);\n\tconst projectsPerPage = Math.max(1, Math.trunc(options.itemsPerPage ?? 20));\n\tconst linearProjects = linearProjectIds(options.linearProjects);\n\n\tconst items: IssueShape[] = [];\n\tconst warnings: ProviderWarning[] = [];\n\tconst emptyPage = (\n\t\tfetchFailed?: boolean,\n\t\ttruncated?: boolean,\n\t\tretry?: {\n\t\t\tnextPage?: number;\n\t\t\tpages?: readonly number[];\n\t\t\tprojects?: readonly string[];\n\t\t\tcompletedProjects?: readonly string[];\n\t\t},\n\t): ProviderPagedResult<IssueShape> => {\n\t\tconst cursor =\n\t\t\tretry != null\n\t\t\t\t? toIssueTrackerPageCursor({\n\t\t\t\t\t\tcurrentPage: page + 1,\n\t\t\t\t\t\tunpaged: !paginated,\n\t\t\t\t\t\tnextPage: retry.nextPage,\n\t\t\t\t\t\tretryPages: retry.pages ?? [],\n\t\t\t\t\t\tretryProjects: retry.projects ?? [],\n\t\t\t\t\t\tcompletedProjects: retry.completedProjects ?? [],\n\t\t\t\t\t\tstate: options.state,\n\t\t\t\t\t\tlinearProjects: linearProjects,\n\t\t\t\t\t})\n\t\t\t\t: undefined;\n\t\treturn {\n\t\t\titems: items,\n\t\t\twarnings: warnings,\n\t\t\tpage: { currentPage: page, itemsPerPage: items.length, truncated: truncated || undefined },\n\t\t\t// Retry-only state is deliberately manual: advertising it as forward progress would make a\n\t\t\t// persistent provider failure spin forever in a normal `while (hasMore)` consumer. An untouched\n\t\t\t// project window remains normal forward progress even when this window failed completely.\n\t\t\thasMore: retry?.nextPage != null && cursor != null,\n\t\t\tcursor: cursor,\n\t\t\tfetchFailed: fetchFailed || undefined,\n\t\t};\n\t};\n\tconst normalWindowPage = paginated\n\t\t? (compositeCursor?.nextPage ?? (compositeCursor == null ? page : undefined))\n\t\t: undefined;\n\tconst priorRetryPages = compositeCursor?.retryPages ?? [];\n\tconst priorRetryProjects = compositeCursor?.retryProjects ?? [];\n\tconst priorCompletedProjects = compositeCursor?.completedProjects ?? [];\n\tconst trackCompletedProjects =\n\t\tpriorCompletedProjects.length > 0 || priorRetryPages.length > 0 || compositeCursor?.completedProjects != null;\n\tconst retryPagesForDiscoveryFailure = (): number[] => [\n\t\t...priorRetryPages,\n\t\t...(normalWindowPage != null ? [normalWindowPage] : compositeCursor == null ? [1] : []),\n\t];\n\tconst discoveryFailureRetry = (): {\n\t\tpages: readonly number[];\n\t\tprojects: readonly string[];\n\t\tcompletedProjects: readonly string[];\n\t} => ({\n\t\tpages: retryPagesForDiscoveryFailure(),\n\t\tprojects: priorRetryProjects,\n\t\tcompletedProjects: priorCompletedProjects,\n\t});\n\n\tif (!isIssuesHostIntegrationId(options.providerId)) {\n\t\twarnings.push(\n\t\t\tissueTrackerOnlySurfaceWarning(options.providerId, options.connectionId, 'Issue-tracker project reads'),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\tconst integration = await ctx.getIntegrationForRead(options.providerId, options.connectionId, options.domain);\n\tif (integration == null) {\n\t\t// A supplied connectionId or domain that no longer resolves is a broken target, not an empty account.\n\t\tconst early = ctx.earlyReturnConnectionWarnings(options.providerId, options.connectionId, options.domain);\n\t\twarnings.push(...early.warnings);\n\t\treturn emptyPage(early.fetchFailed);\n\t}\n\tif (!isIssuesIntegration(integration)) {\n\t\twarnings.push(\n\t\t\tissueTrackerOnlySurfaceWarning(options.providerId, options.connectionId, 'Issue-tracker project reads'),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\tconst domain = ctx.domainForRead(integration, options.providerId, options.connectionId, options.domain);\n\n\t// Before any upstream request: the discovery fan-outs below (resources, projects, per-resource accounts) are\n\t// three round trips, and an order this tracker can't express refuses the read whatever they return. Placed after\n\t// `domain` only because every warning carries it.\n\tconst resolvedSort = resolveIssueSort(providersMetadata[options.providerId]?.supportedIssueSorts, options.sort);\n\tif (resolvedSort.rejection != null) {\n\t\twarnings.push(\n\t\t\tunsupportedIssueSortWarning(options.providerId, domain, options.connectionId, resolvedSort.rejection),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\tconst sort = resolvedSort.sort;\n\n\t// Refused before any request for the same reason as the sort: a state the tracker can't express would otherwise\n\t// be dropped by its project reads, and their open issues published as the requested state. A value outside the\n\t// vocabulary is refused too, since `toProviderIssueStates` would read it as omitted, which means open.\n\tif (\n\t\toptions.state != null &&\n\t\t(!issueStateFilters.includes(options.state) ||\n\t\t\t(options.state !== 'open' && !providersMetadata[options.providerId]?.supportsIssueStates))\n\t) {\n\t\t// A known state this tracker can't express is an unsupported capability; a value outside the vocabulary is\n\t\t// caller input the caller fixes in the request.\n\t\twarnings.push(\n\t\t\tissueStateFilters.includes(options.state)\n\t\t\t\t? unsupportedWarning(\n\t\t\t\t\t\toptions.providerId,\n\t\t\t\t\t\tdomain,\n\t\t\t\t\t\toptions.connectionId,\n\t\t\t\t\t\t`Issue state '${options.state}' is not supported by '${options.providerId}'.`,\n\t\t\t\t\t)\n\t\t\t\t: otherWarning(\n\t\t\t\t\t\toptions.providerId,\n\t\t\t\t\t\tdomain,\n\t\t\t\t\t\toptions.connectionId,\n\t\t\t\t\t\t`Unknown issue state; expected one of ${issueStateFilters.join(', ')}.`,\n\t\t\t\t\t),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\t// A cursor resumed under another state than it was minted for skips what it already covered, whose other-state\n\t// issues were never read. A narrowed read only mints composite cursors, which record their state, so any other\n\t// cursor came from an open read.\n\tconst cursorState =\n\t\tcompositeCursor != null ? (compositeCursor.state ?? 'open') : options.cursor != null ? 'open' : undefined;\n\tif (cursorState != null && cursorState !== (options.state ?? 'open')) {\n\t\twarnings.push(\n\t\t\totherWarning(\n\t\t\t\toptions.providerId,\n\t\t\t\tdomain,\n\t\t\t\toptions.connectionId,\n\t\t\t\t'The cursor belongs to a read of another issue state; start again without it.',\n\t\t\t),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\t// Refused before any request like the state. A value that is not a list of non-empty ids is caller input, refused\n\t// rather than dropped, since dropping it (or its last entry) widens the read to every issue; another tracker would\n\t// ignore it and publish its whole project.\n\tif (options.linearProjects != null) {\n\t\tif (\n\t\t\t!Array.isArray(options.linearProjects) ||\n\t\t\toptions.linearProjects.some(id => typeof id !== 'string' || id.length === 0)\n\t\t) {\n\t\t\twarnings.push(\n\t\t\t\totherWarning(\n\t\t\t\t\toptions.providerId,\n\t\t\t\t\tdomain,\n\t\t\t\t\toptions.connectionId,\n\t\t\t\t\t'Linear Projects must be a list of non-empty ids.',\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn emptyPage(true);\n\t\t}\n\t\tif (options.linearProjects.length > 0 && options.providerId !== IssuesCloudHostIntegrationId.Linear) {\n\t\t\twarnings.push(\n\t\t\t\tunsupportedWarning(\n\t\t\t\t\toptions.providerId,\n\t\t\t\t\tdomain,\n\t\t\t\t\toptions.connectionId,\n\t\t\t\t\t`Narrowing by Linear Project is not supported by '${options.providerId}'.`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn emptyPage(true);\n\t\t}\n\t}\n\n\t// As with the state: a cursor resumed under other Projects skips teams drained under the ones it was minted for.\n\t// Only a composite cursor records them, so any other cursor came from a read narrowed to none.\n\tif (\n\t\toptions.cursor != null &&\n\t\t(compositeCursor?.linearProjects ?? []).join('\\0') !== (linearProjects ?? []).join('\\0')\n\t) {\n\t\twarnings.push(\n\t\t\totherWarning(\n\t\t\t\toptions.providerId,\n\t\t\t\tdomain,\n\t\t\t\toptions.connectionId,\n\t\t\t\t'The cursor belongs to a read of other Linear Projects; start again without it.',\n\t\t\t),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\tawait ctx.forceRefreshIfRequested(integration, options.forceSync, options.connectionId);\n\n\t// A Project id the workspace no longer lists narrows every team to nothing, which would read as a Project with no\n\t// issues. Reported as a selector miss instead, as an `org` or `project` that matches nothing is.\n\tif (linearProjects != null && isLinearIntegration(integration)) {\n\t\tconst missing = await findUnlistedLinearProject(integration, linearProjects, options.connectionId);\n\t\tif (missing != null) {\n\t\t\twarnings.push(\n\t\t\t\tunmatchedSelectorWarning(options.providerId, domain, options.connectionId, {\n\t\t\t\t\tkind: 'linearProject',\n\t\t\t\t\tvalue: missing,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\n\tawait integration.getCurrentAccount({ connectionId: options.connectionId }).catch(() => undefined);\n\n\tconst {\n\t\tvalue: resources,\n\t\twarning: resourcesWarning,\n\t\tmetadata: resourcesMetadata,\n\t} = await discoverResources(integration, options.providerId, domain, options.connectionId);\n\tif (resourcesWarning != null) {\n\t\twarnings.push(resourcesWarning);\n\t}\n\tconst scopedResources =\n\t\toptions.org != null\n\t\t\t? (resources ?? []).filter(r => selectorMatches(options.providerId, r, options.org!))\n\t\t\t: (resources ?? []);\n\t// Only a complete discovery proves a selection gone: a failed one may just not have reached it, and no resource\n\t// list without a warning is no session.\n\tconst resourceDiscoveryComplete = resources != null && resourcesWarning == null;\n\tconst selectionTarget: SelectionTarget = {\n\t\tintegration: integration,\n\t\tproviderId: options.providerId,\n\t\tdomain: domain,\n\t\tconnectionId: options.connectionId,\n\t\torg: options.org,\n\t\tproject: options.project,\n\t};\n\tconst unconfirmed = (reasons: readonly ProviderWarning[]): ProviderPagedResult<IssueShape> => {\n\t\tif (reasons.length === 0) {\n\t\t\twarnings.push(\n\t\t\t\totherWarning(\n\t\t\t\t\toptions.providerId,\n\t\t\t\t\tdomain,\n\t\t\t\t\toptions.connectionId,\n\t\t\t\t\t`Could not confirm '${options.project ?? options.org}' is gone, so it is not reported as removed.`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tfor (const warning of reasons) {\n\t\t\tappendDedupedWarning(warnings, warning);\n\t\t}\n\t\treturn emptyPage(true, false, discoveryFailureRetry());\n\t};\n\t/**\n\t * Settles a selection the cached discovery matches nothing for from the provider's lists as they are now (see\n\t * {@link confirmSelection} and {@link toSelectionAction}). The cached lists can predate what was created since, so\n\t * a stale one is dropped and the read made once more over fresh lists; that read confirms the same way, since its\n\t * own discovery can still be joined to one started before the drop.\n\t */\n\tconst missSelection = async (\n\t\tselector: ProviderWarningSelector & { kind: TrackerSelectorKind },\n\t): Promise<ProviderPagedResult<IssueShape>> => {\n\t\tconst next = toSelectionAction(await confirmSelection(selectionTarget, selector.kind), refreshed);\n\t\tswitch (next.action) {\n\t\t\tcase 'unconfirmed':\n\t\t\t\treturn unconfirmed(next.warnings);\n\t\t\tcase 'refresh':\n\t\t\t\tintegration.invalidateDiscoveryCaches();\n\t\t\t\t// The caches are dropped already: the refreshed read needs no second session sync.\n\t\t\t\treturn readIssueTrackerIssuesPage(ctx, { ...options, forceSync: false }, true);\n\t\t\tcase 'report-missing': {\n\t\t\t\tconst credential = await confirmCredential(selectionTarget, next.resource);\n\t\t\t\tif (!credential.confirmed) {\n\t\t\t\t\treturn unconfirmed(credential.warning != null ? [credential.warning] : []);\n\t\t\t\t}\n\n\t\t\t\t// What the lists miss now: a selected org that is gone misses the org, whichever the cache missed.\n\t\t\t\tconst missed: ProviderWarningSelector =\n\t\t\t\t\tnext.missed === 'org' && options.org != null ? { kind: 'org', value: options.org } : selector;\n\t\t\t\twarnings.push(\n\t\t\t\t\tunmatchedSelectorWarning(options.providerId, domain, options.connectionId, missed, options.org),\n\t\t\t\t);\n\t\t\t\treturn emptyPage();\n\t\t\t}\n\t\t}\n\t};\n\t// Checked before the empty return, since an account with no resources left misses the selection too.\n\tif (options.org != null && resourceDiscoveryComplete && scopedResources.length === 0) {\n\t\treturn missSelection({ kind: 'org', value: options.org });\n\t}\n\tif (resources == null || resources.length === 0) {\n\t\tif (options.project != null && resourceDiscoveryComplete) {\n\t\t\treturn missSelection({ kind: 'project', value: options.project });\n\t\t}\n\n\t\tconst fetchFailed = resourcesWarning != null && resources == null;\n\t\tconst { truncated } = mergeAssessmentInto(\n\t\t\twarnings,\n\t\t\toptions.providerId,\n\t\t\tdomain,\n\t\t\toptions.connectionId,\n\t\t\tresourcesMetadata,\n\t\t);\n\t\treturn emptyPage(fetchFailed, truncated, fetchFailed || truncated ? discoveryFailureRetry() : undefined);\n\t}\n\t// Only a partial discovery, reported by its warning, reaches here without the selected resource.\n\tif (scopedResources.length === 0) {\n\t\treturn emptyPage();\n\t}\n\n\tconst { value: projectsResult, warning: projectsWarning } = await runCaptured(\n\t\toptions.providerId,\n\t\tdomain,\n\t\toptions.connectionId,\n\t\t() => integration.getProjectsForResourcesWithMetadataResult(scopedResources, options.connectionId),\n\t);\n\tif (projectsWarning != null) {\n\t\twarnings.push(projectsWarning);\n\t}\n\t// Partial project discovery: continue with the resources that succeeded, but surface per-resource\n\t// failures as warnings and remember to mark the page fetchFailed so the caller knows some issues may be\n\t// missing. `projectDiscoveryFailed`/`projectDiscoveryTruncated` are OR-ed into the page's\n\t// fetchFailed/truncated at every return below (a truncated-but-not-failed discovery, e.g. a paging\n\t// backstop, still means the project set is incomplete).\n\tconst projectDiscoveryAssessment = mergeAssessmentInto(\n\t\twarnings,\n\t\toptions.providerId,\n\t\tdomain,\n\t\toptions.connectionId,\n\t\tprojectsResult?.metadata,\n\t);\n\tconst projectDiscoveryFailed = projectDiscoveryAssessment.fetchFailed;\n\tconst projectDiscoveryTruncated = projectDiscoveryAssessment.truncated;\n\tconst projects = projectsResult?.values;\n\tconst matchedProjects =\n\t\toptions.project != null\n\t\t\t? (projects ?? []).filter(p => selectorMatches(options.providerId, p, options.project!))\n\t\t\t: (projects ?? []);\n\tconst projectDiscoveryComplete =\n\t\tresourceDiscoveryComplete && projectsWarning == null && !projectDiscoveryFailed && !projectDiscoveryTruncated;\n\tif (options.project != null && projects != null && projectDiscoveryComplete && matchedProjects.length === 0) {\n\t\treturn missSelection({ kind: 'project', value: options.project });\n\t}\n\tif (projects == null || projects.length === 0) {\n\t\tconst fetchFailed = (projectsWarning != null && projectsResult == null) || projectDiscoveryFailed;\n\t\treturn emptyPage(\n\t\t\tfetchFailed,\n\t\t\tprojectDiscoveryTruncated,\n\t\t\tfetchFailed || projectDiscoveryTruncated ? discoveryFailureRetry() : undefined,\n\t\t);\n\t}\n\n\t// Validate the requested filters against what this provider supports (e.g. Linear/Trello support only\n\t// Assignee). An unsupported filter must not silently degrade — Linear/Trello ignore the requested type\n\t// and apply Assignee regardless — so warn + fetchFailed instead of returning a differently-scoped set.\n\tif (options.filters?.length) {\n\t\tconst supported = providersMetadata[options.providerId]?.supportedIssueFilters;\n\t\tconst allSupported = supported != null && options.filters.every(f => supported.includes(f));\n\t\tif (!allSupported) {\n\t\t\twarnings.push(\n\t\t\t\tunsupportedWarning(\n\t\t\t\t\toptions.providerId,\n\t\t\t\t\tdomain,\n\t\t\t\t\toptions.connectionId,\n\t\t\t\t\t`One or more requested issue filters are not supported by '${options.providerId}'.`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn emptyPage(true);\n\t\t}\n\t}\n\n\t// `includeAllAssignees` drops the user scope, but a user-relative filter (Author/Mention) is meaningless\n\t// without a user. Passing both to the provider degrades silently: Jira, seeing no user, falls through to\n\t// an unscoped project fetch and returns EVERY issue instead of the requested author's/mentions. Reject\n\t// the incompatible combination up front rather than publishing a differently-scoped set as the result.\n\tif (options.includeAllAssignees === true && options.filters?.some(f => f !== IssueFilter.Assignee)) {\n\t\twarnings.push(\n\t\t\tunsupportedWarning(\n\t\t\t\toptions.providerId,\n\t\t\t\tdomain,\n\t\t\t\toptions.connectionId,\n\t\t\t\t`\\`includeAllAssignees\\` cannot be combined with an author/mention filter for '${options.providerId}' (those filters require a user scope).`,\n\t\t\t),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\t// Scope to the current user's issues unless the caller broadens to all assignees. Resolve the\n\t// handle from each resource's own account (multi-account safe), capturing any error so its kind\n\t// (e.g. auth) is preserved rather than collapsed to a generic warning.\n\tlet usersByResourceId: Map<string, string> | undefined;\n\t// The same accounts keyed by the same resource, holding the provider's stable id rather than the handle. A\n\t// separate map rather than a widened value because the two are resolved and consumed independently: a\n\t// provider may carry an account with no id, and `scopedProjectsWithUsers` gates on the HANDLE alone, so\n\t// folding them together would drop a resource whose id happened to be missing.\n\tlet userIdsByResourceId: Map<string, string> | undefined;\n\tlet accountLookupFailed = false;\n\tif (options.includeAllAssignees !== true) {\n\t\tusersByResourceId = new Map<string, string>();\n\t\tuserIdsByResourceId = new Map<string, string>();\n\t\tconst accounts = await mapBounded(scopedResources, providerFanOutConcurrency, async resource => ({\n\t\t\tresource: resource,\n\t\t\t...(await runCaptured(options.providerId, domain, options.connectionId, () =>\n\t\t\t\tintegration.getAccountForResourceResult(resource, options.connectionId),\n\t\t\t)),\n\t\t}));\n\n\t\tfor (const { resource, value: account, warning: accountWarning } of accounts) {\n\t\t\tconst user = account?.username ?? account?.name ?? undefined;\n\t\t\tif (user != null) {\n\t\t\t\tconst resourceKey = resourceIdForProject(resource) ?? resource.key;\n\t\t\t\tusersByResourceId.set(resourceKey, user);\n\t\t\t\t// Empty-checked, not just null-checked: an account shape declares `id` as a plain string, and a\n\t\t\t\t// provider with nothing to put there sets `''` rather than omitting it — which would otherwise\n\t\t\t\t// reach a user-field query as an empty identity and match nothing.\n\t\t\t\tif (account?.id != null && account.id !== '') {\n\t\t\t\t\tuserIdsByResourceId.set(resourceKey, account.id);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Deduped: a captured `accountWarning` carries only the provider error, with no resource in its\n\t\t\t// message, so one expired token across N resources would otherwise repeat verbatim N times. The\n\t\t\t// synthesized fallback names the resource, so those stay distinct on their own.\n\t\t\tappendDedupedWarning(\n\t\t\t\twarnings,\n\t\t\t\taccountWarning ??\n\t\t\t\t\totherWarning(\n\t\t\t\t\t\toptions.providerId,\n\t\t\t\t\t\tdomain,\n\t\t\t\t\t\toptions.connectionId,\n\t\t\t\t\t\t`Could not resolve the current user for '${resourceLabel(resource)}'; skipping that resource to avoid returning issues assigned to others.`,\n\t\t\t\t\t),\n\t\t\t);\n\t\t\taccountLookupFailed = true;\n\t\t}\n\t}\n\n\tconst fallbackUserForUnscopedProject =\n\t\tscopedResources.length === 1 && usersByResourceId?.size === 1\n\t\t\t? usersByResourceId.values().next().value\n\t\t\t: undefined;\n\tconst userForProject = (project: ResourceDescriptor): string | undefined => {\n\t\tconst resourceId = resourceIdForProject(project);\n\t\tif (resourceId != null) {\n\t\t\tconst user = usersByResourceId?.get(resourceId);\n\t\t\tif (user != null) {\n\t\t\t\treturn user;\n\t\t\t}\n\t\t}\n\n\t\t// Some providers/tests return project descriptors without their parent resource id. When we have only\n\t\t// one scoped resource, re-use that sole resolved user rather than silently dropping every project.\n\t\treturn fallbackUserForUnscopedProject;\n\t};\n\t// Deliberately NOT falling back the way `userForProject` does. That fallback exists so a project with no\n\t// parent resource id still gets scoped rather than dropped, and the handle is what the drop is judged on;\n\t// the id is optional everywhere it is read, so a miss degrades to the handle instead of widening the read.\n\tconst userIdForProject = (project: ResourceDescriptor): string | undefined => {\n\t\tconst resourceId = resourceIdForProject(project);\n\t\treturn resourceId != null ? userIdsByResourceId?.get(resourceId) : undefined;\n\t};\n\n\tconst retryProjectKeys = new Set<string>();\n\tconst completedProjectKeys = new Set(priorCompletedProjects);\n\tfor (const retryProject of priorRetryProjects) {\n\t\tcompletedProjectKeys.delete(retryProject);\n\t}\n\tconst scopedProjectsWithUsers =\n\t\tusersByResourceId != null\n\t\t\t? matchedProjects.filter(project => {\n\t\t\t\t\tif (userForProject(project) != null) return true;\n\n\t\t\t\t\tconst key = projectKey(project);\n\t\t\t\t\tretryProjectKeys.add(key);\n\t\t\t\t\tcompletedProjectKeys.delete(key);\n\t\t\t\t\treturn false;\n\t\t\t\t})\n\t\t\t: matchedProjects;\n\n\t// Select the untouched window plus any earlier windows/projects that explicitly need retrying. Keys\n\t// include the parent resource so two trackers can reuse the same project id without collapsing.\n\tconst projectsByRetryKey = new Map(scopedProjectsWithUsers.map(project => [projectKey(project), project]));\n\tconst scopedProjectsByKey = new Map<string, ResourceDescriptor>();\n\tconst addScopedProject = (project: ResourceDescriptor): void => {\n\t\tconst key = projectKey(project);\n\t\tif (completedProjectKeys.has(key)) return;\n\n\t\tscopedProjectsByKey.set(key, project);\n\t};\n\tfor (const retryProject of priorRetryProjects) {\n\t\tconst project = projectsByRetryKey.get(retryProject);\n\t\tif (project != null) {\n\t\t\taddScopedProject(project);\n\t\t} else if (projectDiscoveryFailed || projectDiscoveryTruncated) {\n\t\t\tretryProjectKeys.add(retryProject);\n\t\t}\n\t}\n\tconst windowPages = new Set<number>(priorRetryPages);\n\tif (normalWindowPage != null) {\n\t\twindowPages.add(normalWindowPage);\n\t}\n\tif (!paginated && (projectDiscoveryFailed || projectDiscoveryTruncated)) {\n\t\twindowPages.add(1);\n\t}\n\tif (paginated) {\n\t\tfor (const windowPage of windowPages) {\n\t\t\tconst windowStart = (windowPage - 1) * projectsPerPage;\n\t\t\tfor (const project of scopedProjectsWithUsers.slice(windowStart, windowStart + projectsPerPage)) {\n\t\t\t\taddScopedProject(project);\n\t\t\t}\n\t\t}\n\t} else if (compositeCursor == null || priorRetryPages.length > 0) {\n\t\t// An unpaged retry-only cursor should re-read only the explicitly failed projects already added\n\t\t// above. Discovery retries still rescan the aggregate set so newly recovered projects are included.\n\t\tfor (const project of scopedProjectsWithUsers) {\n\t\t\taddScopedProject(project);\n\t\t}\n\t}\n\tconst scopedProjects = [...scopedProjectsByKey.values()];\n\tconst furthestWindowPage = windowPages.size > 0 ? Math.max(...windowPages) : normalWindowPage;\n\tconst normalWindowEnd =\n\t\tfurthestWindowPage != null ? furthestWindowPage * projectsPerPage : scopedProjectsWithUsers.length;\n\tconst nextPage =\n\t\tpaginated && furthestWindowPage != null && scopedProjectsWithUsers.length > normalWindowEnd\n\t\t\t? furthestWindowPage + 1\n\t\t\t: undefined;\n\tconst retryWindowPages = (): number[] => {\n\t\tif (!projectDiscoveryFailed && !projectDiscoveryTruncated && retryProjectKeys.size === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst pages = new Set(windowPages);\n\t\tif (pages.size === 0) {\n\t\t\t// A terminal retry has no untouched next window to identify its origin. Keep a manual window\n\t\t\t// marker so a later partial discovery can reconcile against the projects already emitted.\n\t\t\tpages.add(paginated ? Math.max(1, page - 1) : 1);\n\t\t}\n\t\treturn [...pages];\n\t};\n\tif (scopedProjects.length === 0) {\n\t\t// The discovered projects didn't intersect the requested filter/window, or every matching resource\n\t\t// failed user resolution. If discovery or account lookup was partial, the empty result is not a\n\t\t// proven-empty account — carry `fetchFailed` so the caller knows issues may be missing.\n\t\treturn emptyPage(projectDiscoveryFailed || accountLookupFailed, projectDiscoveryTruncated, {\n\t\t\tnextPage: nextPage,\n\t\t\tpages: retryWindowPages(),\n\t\t\tprojects: [...retryProjectKeys],\n\t\t\tcompletedProjects: [...completedProjectKeys],\n\t\t});\n\t}\n\n\t// A read spanning several projects is a merge, so it can only honor a key a normalized issue carries. Bound here\n\t// rather than next to the key's validation above, because the project count is only known now — while still\n\t// before any project read, so a refusal costs no request. Refused rather than served as concatenated\n\t// per-project runs, which would look ordered without being so.\n\t//\n\t// Counted over every project the READ covers, not the `scopedProjects` window this page happens to hold: the\n\t// window is `itemsPerPage` projects wide, so counting it would refuse a 20-project page and then serve the\n\t// final 1-project page of the same paginated call — the same key answered two ways, with the earlier pages'\n\t// issues missing from a read that reported success.\n\t//\n\t// Projects are not the only thing a tracker read merges: a user-scoped read asking for several relationships\n\t// issues one provider query PER relationship and unions them within each project (Jira runs one JQL drain per\n\t// filter and folds them into one map, in filter order), so a single-project page of two filters is just as\n\t// concatenated as a two-project one. Counting only projects published those runs under the requested key.\n\t// Not gated on the provider: the two trackers that don't fan out (Linear, Trello) declare `Assignee` as their\n\t// only supported filter, so a multi-filter read is already refused above and can never reach this.\n\tconst mergesFilters = options.includeAllAssignees !== true && (options.filters?.length ?? 0) > 1;\n\tconst ordering = toIssueOrdering(sort, scopedProjectsWithUsers.length > 1 || mergesFilters);\n\tif (ordering.unmergeable != null) {\n\t\twarnings.push(\n\t\t\tunmergeableIssueSortWarning(\n\t\t\t\toptions.providerId,\n\t\t\t\tdomain,\n\t\t\t\toptions.connectionId,\n\t\t\t\tordering.unmergeable,\n\t\t\t\tscopedProjectsWithUsers.length > 1 ? 'projects' : 'filters',\n\t\t\t),\n\t\t);\n\t\treturn emptyPage(true);\n\t}\n\n\t// One call for the whole window, so a tracker that can search several projects at once (Jira) does, instead\n\t// of paying one drain per project. Results still come back per project, which the accounting below needs.\n\tlet projectReads: IntegrationResult<ProjectIssuesDrain | undefined>[];\n\ttry {\n\t\tprojectReads = await integration.getIssuesForProjectsWithTruncationResult(\n\t\t\tscopedProjects.map(project => ({\n\t\t\t\tproject: project,\n\t\t\t\toptions: {\n\t\t\t\t\tuser: userForProject(project),\n\t\t\t\t\tuserId: userIdForProject(project),\n\t\t\t\t\tfilters: options.filters,\n\t\t\t\t\tsort: sort,\n\t\t\t\t\tstate: options.state,\n\t\t\t\t\t...(linearProjects != null ? { linearProjects: linearProjects } : {}),\n\t\t\t\t},\n\t\t\t})),\n\t\t\toptions.connectionId,\n\t\t);\n\t} catch (ex) {\n\t\tconst error = toError(ex);\n\t\tprojectReads = scopedProjects.map(() => ({ error: error }));\n\t}\n\tconst perProject = await Promise.all(\n\t\tscopedProjects.map(async (project, index) => ({\n\t\t\tproject: project,\n\t\t\t...(await runCaptured(options.providerId, domain, options.connectionId, () =>\n\t\t\t\tPromise.resolve(projectReads[index]),\n\t\t\t)),\n\t\t})),\n\t);\n\t// Partial project discovery means some projects' issues are missing from this page; propagate it so the\n\t// page reports fetchFailed even when every discovered project's own read succeeded.\n\tlet fetchFailed = projectDiscoveryFailed || accountLookupFailed;\n\t// Whether a request failed, which `fetchFailed` alone doesn't say: see `assessCollectionMetadata`'s `requestFailed`.\n\tlet requestFailed = fetchFailed;\n\tlet truncated = projectDiscoveryTruncated;\n\t// The projects whose read stopped short with nothing in its metadata to say why. One whose provider names its scope\n\t// is reported on its own, even when the read also failed: a project's cut must not hide behind another's failure,\n\t// which may be no more than an issue it skipped (#6011), nor its recovery behind another project's.\n\tconst cuts: { project: ResourceDescriptor; recovery: ProjectIssuesRecovery; scope: CollectionScope }[] = [];\n\tlet drainMetadata: CollectionMetadata | undefined;\n\tfor (const { project, value: result, warning } of perProject) {\n\t\tconst key = projectKey(project);\n\t\tconst retryProject = result == null;\n\t\tif (warning != null) {\n\t\t\t// Deduped: the per-project warning is built from the provider error alone and names no project, so a\n\t\t\t// single failing token repeats verbatim once per project in the window.\n\t\t\tappendDedupedWarning(warnings, warning);\n\t\t\tfetchFailed = true;\n\t\t\trequestFailed = true;\n\t\t\ttruncated = true;\n\t\t}\n\t\t// A thrown/unsupported read (e.g. Linear not-implemented) surfaces as a warning with no value;\n\t\t// mark the aggregate as fetchFailed so an empty result isn't mistaken for \"no issues\".\n\t\tif (result == null) {\n\t\t\tfetchFailed = true;\n\t\t\trequestFailed = true;\n\t\t}\n\t\tif (result != null) {\n\t\t\titems.push(...result.values);\n\t\t\tif (result.truncated) {\n\t\t\t\ttruncated = true;\n\t\t\t\tif (result.scope != null && !result.metadata?.failures?.length && !result.metadata?.omissions?.length) {\n\t\t\t\t\tcuts.push({ project: project, recovery: result.recovery, scope: result.scope });\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (result.metadata != null) {\n\t\t\t\tdrainMetadata = mergeCollectionMetadata(drainMetadata, result.metadata);\n\t\t\t}\n\t\t}\n\t\tif (retryProject) {\n\t\t\tretryProjectKeys.add(key);\n\t\t\tcompletedProjectKeys.delete(key);\n\t\t} else {\n\t\t\t// A usable partial/truncated project is emitted once and remains structurally incomplete.\n\t\t\t// Re-running the same project cursor would normally return the same prefix and duplicate it\n\t\t\t// across facade pages; only a project that returned no value is safe to retry automatically.\n\t\t\tcompletedProjectKeys.add(key);\n\t\t}\n\t}\n\n\t// Each provider query arrived ordered by the tracker; the union of them — across projects, and across the\n\t// per-relationship queries a multi-filter read fans out into — is not, and the union is what this read\n\t// publishes. A no-op when nothing merged, since the tracker already ordered that single run.\n\tconst orderedItems = ordering.order(items);\n\n\tconst drainAssessment = assessCollectionMetadata(options.providerId, domain, options.connectionId, drainMetadata);\n\tfor (const warning of drainAssessment.warnings) {\n\t\t// The truncation the projects reported already gets a structured warning below. Replace metadata's unstructured\n\t\t// fallback, the only warning it raises when nothing failed and nothing was omitted, while retaining failures and\n\t\t// omissions.\n\t\tif (truncated && !drainAssessment.fetchFailed && warning.omission == null) continue;\n\n\t\tappendDedupedWarning(warnings, warning);\n\t}\n\tfetchFailed = fetchFailed || drainAssessment.fetchFailed;\n\trequestFailed = requestFailed || drainAssessment.requestFailed;\n\ttruncated = truncated || drainAssessment.truncated;\n\n\tfor (const { project, recovery, scope } of cuts) {\n\t\tappendDedupedWarning(\n\t\t\twarnings,\n\t\t\tprojectCutWarning(\n\t\t\t\toptions.providerId,\n\t\t\t\tdomain,\n\t\t\t\toptions.connectionId,\n\t\t\t\tresourceLabel(project),\n\t\t\t\trecovery,\n\t\t\t\tscope,\n\t\t\t),\n\t\t);\n\t}\n\t// A truncation no project's own warning accounts for (a project list read short, or a cut from a provider that names\n\t// no scope for its projects) is reported for the read as a whole, unless a failure or an omission explains it. On\n\t// `fetchFailed`, not `requestFailed`: an issue left unread truncates the read too, and its own warning explains that.\n\t// A project list read short publishes its own warning, so it is never left to an unreadable issue's alone.\n\tif (!fetchFailed && truncated && !warnings.some(warning => warning.omission != null)) {\n\t\tappendDedupedWarning(\n\t\t\twarnings,\n\t\t\tincompleteReadWarning(\n\t\t\t\toptions.providerId,\n\t\t\t\tdomain,\n\t\t\t\toptions.connectionId,\n\t\t\t\t'Some issues were omitted; the provider returned an incomplete result.',\n\t\t\t\t'exhausted',\n\t\t\t),\n\t\t);\n\t}\n\t// A metadata omission from an earlier project asserts the read succeeded; a later one may since have failed.\n\treconcileOmissionsWithFailure(warnings, requestFailed);\n\n\tconst retryPages = retryWindowPages();\n\tconst cursor = toIssueTrackerPageCursor({\n\t\tcurrentPage: page + 1,\n\t\tunpaged: !paginated,\n\t\tnextPage: nextPage,\n\t\tretryPages: retryPages,\n\t\tretryProjects: [...retryProjectKeys],\n\t\tcompletedProjects:\n\t\t\t(trackCompletedProjects ||\n\t\t\t\tprojectDiscoveryFailed ||\n\t\t\t\tprojectDiscoveryTruncated ||\n\t\t\t\tretryProjectKeys.size > 0) &&\n\t\t\t(retryPages.length > 0 || nextPage != null)\n\t\t\t\t? [...completedProjectKeys]\n\t\t\t\t: [],\n\t\tstate: options.state,\n\t\tlinearProjects: linearProjects,\n\t});\n\treturn {\n\t\titems: orderedItems,\n\t\twarnings: warnings,\n\t\tpage: { currentPage: page, itemsPerPage: orderedItems.length, truncated: truncated || undefined },\n\t\t// Failed-project retries alone are manual. Only an untouched project window is automatic progress.\n\t\thasMore: nextPage != null && cursor != null,\n\t\tcursor: cursor,\n\t\tfetchFailed: fetchFailed || undefined,\n\t\trequestFailed: requestFailed,\n\t\tunexpectedGap: nextPage != null && cursor == null,\n\t};\n}\n\n/**\n * The first of `ids` the workspace's Projects don't list, confirmed against a list read past the cache, since a cached\n * one can predate a Project created since. Undefined when every id is listed, or when no complete list can prove one\n * missing: the read then goes ahead, and an id that names nothing reads as empty.\n */\nasync function findUnlistedLinearProject(\n\tintegration: LinearIntegration,\n\tids: readonly string[],\n\tconnectionId: string | undefined,\n): Promise<string | undefined> {\n\tlet unlisted: string | undefined;\n\tfor (const fresh of [false, true]) {\n\t\tconst projects = (await integration.getWorkspaceProjectsResult(connectionId, { fresh: fresh }))?.value;\n\t\tif (\n\t\t\tprojects == null ||\n\t\t\tprojects.truncated === true ||\n\t\t\t(projects.metadata != null && projects.metadata.completeness !== 'complete')\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst listed = new Set(projects.values.map(project => project.id));\n\t\tunlisted = ids.find(id => !listed.has(id));\n\t\tif (unlisted == null) return undefined;\n\t}\n\treturn unlisted;\n}\n"],"mappings":"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"}
|
|
@@ -2,10 +2,10 @@ import { getScopedLogger, maybeStartScopedLogger } from "../../logger.scoped.js"
|
|
|
2
2
|
import { normalizePath } from "../../path.js";
|
|
3
3
|
import { isWindows } from "./platform.js";
|
|
4
4
|
import { join } from "path";
|
|
5
|
-
import { stat } from "fs/promises";
|
|
6
|
-
import * as process from "process";
|
|
7
5
|
import { exec, execFile, spawn } from "child_process";
|
|
8
6
|
import { access, constants } from "fs";
|
|
7
|
+
import { stat } from "fs/promises";
|
|
8
|
+
import * as process from "process";
|
|
9
9
|
//#region ../utils/src/env/node/exec.ts
|
|
10
10
|
var RunError = class extends Error {
|
|
11
11
|
cmd;
|
package/docs/integrations.md
CHANGED
|
@@ -1284,7 +1284,10 @@ as "unset". The sort vocabulary is narrower than the issue search's on purpose:
|
|
|
1284
1284
|
by a field a normalized pull request carries, and GitHub PRs have neither a priority nor a relevance that ranks
|
|
1285
1285
|
stably under the result ceiling.
|
|
1286
1286
|
Issue filters: GitHub/GHE + Azure + Jira `Author, Assignee, Mention` · GitLab `Author, Assignee` ·
|
|
1287
|
-
Linear + Trello `Assignee` · Bitbucket family none.
|
|
1287
|
+
Linear + Trello `Assignee` · Bitbucket family none. With no filter, Linear's user-scoped tracker read is the viewer's
|
|
1288
|
+
assigned issues plus the GitHub-synced issues the viewer created (a GitHub issue attachment, and `syncedWith` not
|
|
1289
|
+
`[]`), since Linear's GitHub Issues sync gives the copy of a GitHub issue its author (when linked) as creator but no
|
|
1290
|
+
assignee; `Assignee` by name reads the assigned issues only.
|
|
1288
1291
|
Account-wide issue filters: GitHub/GHE `Author, Assignee, Mention` · Azure `Author, Assignee` · GitLab
|
|
1289
1292
|
`Assignee, Author` · everything else none.
|
|
1290
1293
|
Issue **search** criteria (`getSupportedFilters().issueSearch`): GitHub/GHE express all of them —
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gitkraken/core-gitlens",
|
|
3
3
|
"description": "GitLens core — shared Git / AI / GitHub primitives for internal GitKraken consumption",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.24.0",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "GitKraken",
|
|
@@ -239,7 +239,7 @@
|
|
|
239
239
|
}
|
|
240
240
|
},
|
|
241
241
|
"dependencies": {
|
|
242
|
-
"@gitkraken/provider-apis": "0.65.
|
|
242
|
+
"@gitkraken/provider-apis": "0.65.7",
|
|
243
243
|
"@octokit/graphql": "9.0.4",
|
|
244
244
|
"@octokit/request": "10.0.14",
|
|
245
245
|
"@octokit/request-error": "7.1.1",
|