mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 09:07:40 +00:00
Expose and validate the existing workspace link fields, preserving omitted values and provider identity checks. Related: https://github.com/stablyai/orca/pull/22609 Co-authored-by: marco song <marco.song@mvlchain.io> Co-authored-by: SongMarco <20613630+SongMarco@users.noreply.github.com> Co-authored-by: Luca Critelli <lucacri@gmail.com> Co-authored-by: Neil <neil@stably.ai>
54 lines
2.1 KiB
TypeScript
54 lines
2.1 KiB
TypeScript
import { parseRemoteProjectRefCandidate } from '../../main/gitlab/project-ref-parser'
|
||
import type { Repo } from '../../shared/repo-types'
|
||
import type { RuntimeWorktreeRecord } from '../../shared/runtime-types'
|
||
import { parseGitLabIssueOrMRLink, type ProjectSlug } from '../../shared/new-workspace/gitlab-links'
|
||
import { RuntimeClientError, type RuntimeClient } from '../runtime-client'
|
||
|
||
export async function assertGitLabLinkFlagProjectsMatch(
|
||
flags: Map<string, string | boolean>,
|
||
client: RuntimeClient,
|
||
target: { repo: string } | { worktree: string }
|
||
): Promise<void> {
|
||
const projects = ['gitlab-issue', 'gitlab-mr'].flatMap((name) => {
|
||
const value = flags.get(name)
|
||
const link =
|
||
typeof value === 'string' && /^https?:\/\//i.test(value.trim())
|
||
? parseGitLabIssueOrMRLink(value)
|
||
: null
|
||
return link ? [link.slug] : []
|
||
})
|
||
if (projects.length === 0) {
|
||
return
|
||
}
|
||
|
||
let project: ProjectSlug | null = null
|
||
let repo: string
|
||
if ('worktree' in target) {
|
||
const result = await client.call<{ worktree: RuntimeWorktreeRecord }>('worktree.show', target)
|
||
const context = result.result.worktree.linkedTaskSourceContext
|
||
const identity = context?.providerIdentity
|
||
if (context?.provider === 'gitlab' && identity?.provider === 'gitlab' && identity.webUrl) {
|
||
project = parseRemoteProjectRefCandidate(identity.webUrl)
|
||
}
|
||
repo = `id:${result.result.worktree.repoId}`
|
||
} else {
|
||
repo = target.repo
|
||
}
|
||
if (!project) {
|
||
const result = await client.call<{ repo: Repo }>('repo.show', { repo })
|
||
const remoteUrl = result.result.repo.gitRemoteIdentity?.remoteUrl
|
||
project = remoteUrl ? parseRemoteProjectRefCandidate(remoteUrl) : null
|
||
}
|
||
|
||
// Numeric slots cannot retain a pasted URL's foreign host or project.
|
||
if (
|
||
!project ||
|
||
projects.some((link) => link.host !== project.host || link.path !== project.path)
|
||
) {
|
||
throw new RuntimeClientError(
|
||
'invalid_argument',
|
||
'The GitLab URL must match the workspace source project or the repository’s stored remote. Use a number for an item in that project; URLs cannot choose a different project.'
|
||
)
|
||
}
|
||
}
|