diff --git a/packages/backend/src/constants.ts b/packages/backend/src/constants.ts index 9ba858de..cc52ef79 100644 --- a/packages/backend/src/constants.ts +++ b/packages/backend/src/constants.ts @@ -1,11 +1,12 @@ +import { CodeHostType } from "@sourcebot/db"; import { env } from "./env.js"; import path from "path"; export const SINGLE_TENANT_ORG_ID = 1; export const PERMISSION_SYNC_SUPPORTED_CODE_HOST_TYPES = [ - 'github', - 'gitlab', + CodeHostType.github, + CodeHostType.gitlab, ]; export const REPOS_CACHE_DIR = path.join(env.DATA_CACHE_DIR, 'repos'); diff --git a/packages/backend/src/repoCompileUtils.ts b/packages/backend/src/repoCompileUtils.ts index 8e8b1f26..d3172543 100644 --- a/packages/backend/src/repoCompileUtils.ts +++ b/packages/backend/src/repoCompileUtils.ts @@ -7,7 +7,7 @@ import { BitbucketRepository, getBitbucketReposFromConfig } from "./bitbucket.js import { getAzureDevOpsReposFromConfig } from "./azuredevops.js"; import { SchemaRestRepository as BitbucketServerRepository } from "@coderabbitai/bitbucket/server/openapi"; import { SchemaRepository as BitbucketCloudRepository } from "@coderabbitai/bitbucket/cloud/openapi"; -import { Prisma, PrismaClient } from '@sourcebot/db'; +import { CodeHostType, Prisma, PrismaClient } from '@sourcebot/db'; import { WithRequired } from "./types.js" import { marshalBool } from "./utils.js"; import { createLogger } from '@sourcebot/logger'; @@ -392,7 +392,7 @@ export const compileBitbucketConfig = async ( const repos = bitbucketRepos.map((repo) => { const isServer = config.deploymentType === 'server'; - const codeHostType = isServer ? 'bitbucket-server' : 'bitbucket-cloud'; // zoekt expects bitbucket-server + const codeHostType: CodeHostType = isServer ? 'bitbucketServer' : 'bitbucketCloud'; const displayName = isServer ? (repo as BitbucketServerRepository).name! : (repo as BitbucketCloudRepository).full_name!; const externalId = isServer ? (repo as BitbucketServerRepository).id!.toString() : (repo as BitbucketCloudRepository).uuid!; const isPublic = isServer ? (repo as BitbucketServerRepository).public : (repo as BitbucketCloudRepository).is_private === false; @@ -425,7 +425,8 @@ export const compileBitbucketConfig = async ( }, metadata: { gitConfig: { - 'zoekt.web-url-type': codeHostType, + // zoekt expects bitbucket-server and bitbucket-cloud + 'zoekt.web-url-type': codeHostType === 'bitbucketServer' ? 'bitbucket-server' : 'bitbucket-cloud', 'zoekt.web-url': webUrl, 'zoekt.name': repoName, 'zoekt.archived': marshalBool(isArchived), @@ -507,7 +508,7 @@ export const compileGenericGitHostConfig_file = async ( const repoName = path.join(remoteUrl.host, remoteUrl.pathname.replace(/\.git$/, '')); const repo: RepoData = { - external_codeHostType: 'generic-git-host', + external_codeHostType: 'genericGitHost', external_codeHostUrl: remoteUrl.resource, external_id: remoteUrl.toString(), cloneUrl: `file://${repoPath}`, @@ -571,7 +572,7 @@ export const compileGenericGitHostConfig_url = async ( const repoName = path.join(remoteUrl.host, remoteUrl.pathname.replace(/\.git$/, '')); const repo: RepoData = { - external_codeHostType: 'generic-git-host', + external_codeHostType: 'genericGitHost', external_codeHostUrl: remoteUrl.origin, external_id: remoteUrl.toString(), cloneUrl: remoteUrl.toString(), diff --git a/packages/backend/src/utils.ts b/packages/backend/src/utils.ts index 4bb18549..0fe98098 100644 --- a/packages/backend/src/utils.ts +++ b/packages/backend/src/utils.ts @@ -59,7 +59,7 @@ export const getRepoPath = (repo: Repo): { path: string, isReadOnly: boolean } = // If we are dealing with a local repository, then use that as the path. // Mark as read-only since we aren't guaranteed to have write access to the local filesystem. const cloneUrl = new URL(repo.cloneUrl); - if (repo.external_codeHostType === 'generic-git-host' && cloneUrl.protocol === 'file:') { + if (repo.external_codeHostType === 'genericGitHost' && cloneUrl.protocol === 'file:') { return { path: cloneUrl.pathname, isReadOnly: true, diff --git a/packages/web/src/app/[domain]/chat/components/demoCards.tsx b/packages/web/src/app/[domain]/chat/components/demoCards.tsx index 5c8d4e5c..7c4fe316 100644 --- a/packages/web/src/app/[domain]/chat/components/demoCards.tsx +++ b/packages/web/src/app/[domain]/chat/components/demoCards.tsx @@ -7,9 +7,10 @@ import { Badge } from "@/components/ui/badge"; import { Card } from "@/components/ui/card"; import { CardContent } from "@/components/ui/card"; import { DemoExamples, DemoSearchExample, DemoSearchScope } from "@/types"; -import { cn, CodeHostType, getCodeHostIcon } from "@/lib/utils"; +import { cn, getCodeHostIcon } from "@/lib/utils"; import useCaptureEvent from "@/hooks/useCaptureEvent"; import { SearchScopeInfoCard } from "@/features/chat/components/chatBox/searchScopeInfoCard"; +import { CodeHostType } from "@sourcebot/db"; interface DemoCards { demoExamples: DemoExamples; diff --git a/packages/web/src/app/[domain]/components/configEditor.tsx b/packages/web/src/app/[domain]/components/configEditor.tsx index 772350d9..63ba1acd 100644 --- a/packages/web/src/app/[domain]/components/configEditor.tsx +++ b/packages/web/src/app/[domain]/components/configEditor.tsx @@ -12,8 +12,8 @@ import { Separator } from "@/components/ui/separator"; import { Schema } from "ajv"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import useCaptureEvent from "@/hooks/useCaptureEvent"; -import { CodeHostType } from "@/lib/utils"; import { useCodeMirrorTheme } from "@/hooks/useCodeMirrorTheme"; +import { CodeHostType } from "@sourcebot/db"; export type QuickActionFn = (previous: T) => T; export type QuickAction = { diff --git a/packages/web/src/app/[domain]/components/importSecretDialog.tsx b/packages/web/src/app/[domain]/components/importSecretDialog.tsx index b67fea7a..23d8aefe 100644 --- a/packages/web/src/app/[domain]/components/importSecretDialog.tsx +++ b/packages/web/src/app/[domain]/components/importSecretDialog.tsx @@ -9,10 +9,11 @@ import { Input } from "@/components/ui/input"; import { Separator } from "@/components/ui/separator"; import useCaptureEvent from "@/hooks/useCaptureEvent"; import { useDomain } from "@/hooks/useDomain"; -import { CodeHostType, isServiceError } from "@/lib/utils"; +import { isServiceError } from "@/lib/utils"; import githubPatCreation from "@/public/github_pat_creation.png"; import gitlabPatCreation from "@/public/gitlab_pat_creation.png"; import giteaPatCreation from "@/public/gitea_pat_creation.png"; +import { CodeHostType } from "@sourcebot/db"; import { zodResolver } from "@hookform/resolvers/zod"; import { Eye, EyeOff, Loader2 } from "lucide-react"; import Image from "next/image"; @@ -88,9 +89,9 @@ export const ImportSecretDialog = ({ open, onOpenChange, onSecretCreated, codeHo return ; case 'gitlab': return ; - case 'bitbucket-cloud': + case 'bitbucketCloud': return ; - case 'bitbucket-server': + case 'bitbucketServer': return ; case 'gitea': return ; diff --git a/packages/web/src/app/[domain]/repos/components/repoBranchesTable.tsx b/packages/web/src/app/[domain]/repos/components/repoBranchesTable.tsx index bc186acd..eea5e102 100644 --- a/packages/web/src/app/[domain]/repos/components/repoBranchesTable.tsx +++ b/packages/web/src/app/[domain]/repos/components/repoBranchesTable.tsx @@ -15,13 +15,14 @@ import { import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" -import { CodeHostType, getCodeHostBrowseAtBranchUrl } from "@/lib/utils" +import { getCodeHostBrowseAtBranchUrl } from "@/lib/utils" import Link from "next/link" +import { CodeHostType } from "@sourcebot/db"; type RepoBranchesTableProps = { indexRevisions: string[]; repoWebUrl: string | null; - repoCodeHostType: string; + repoCodeHostType: CodeHostType; } export const RepoBranchesTable = ({ indexRevisions, repoWebUrl, repoCodeHostType }: RepoBranchesTableProps) => { @@ -39,7 +40,7 @@ export const RepoBranchesTable = ({ indexRevisions, repoWebUrl, repoCodeHostType const branchUrl = getCodeHostBrowseAtBranchUrl({ webUrl: repoWebUrl, - codeHostType: repoCodeHostType as CodeHostType, + codeHostType: repoCodeHostType, branchName: refName, }); diff --git a/packages/web/src/app/[domain]/repos/components/reposTable.tsx b/packages/web/src/app/[domain]/repos/components/reposTable.tsx index c767acbc..77d03883 100644 --- a/packages/web/src/app/[domain]/repos/components/reposTable.tsx +++ b/packages/web/src/app/[domain]/repos/components/reposTable.tsx @@ -14,7 +14,7 @@ import { Input } from "@/components/ui/input" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { SINGLE_TENANT_ORG_DOMAIN } from "@/lib/constants" -import { cn, CodeHostType, getCodeHostCommitUrl, getCodeHostIcon, getCodeHostInfoForRepo, getRepoImageSrc } from "@/lib/utils" +import { cn, getCodeHostCommitUrl, getCodeHostIcon, getCodeHostInfoForRepo, getRepoImageSrc } from "@/lib/utils" import { type ColumnDef, type ColumnFiltersState, @@ -38,6 +38,7 @@ import { useToast } from "@/components/hooks/use-toast"; import { DisplayDate } from "../../components/DisplayDate" import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip" import { NotificationDot } from "../../components/notificationDot" +import { CodeHostType } from "@sourcebot/db" // @see: https://v0.app/chat/repo-indexing-status-uhjdDim8OUS @@ -50,7 +51,7 @@ export type Repo = { indexedAt: Date | null createdAt: Date webUrl: string | null - codeHostType: string + codeHostType: CodeHostType imageUrl: string | null indexedCommitHash: string | null latestJobStatus: "PENDING" | "IN_PROGRESS" | "COMPLETED" | "FAILED" | null @@ -97,7 +98,7 @@ export const columns: ColumnDef[] = [ }, cell: ({ row }) => { const repo = row.original; - const codeHostIcon = getCodeHostIcon(repo.codeHostType as CodeHostType); + const codeHostIcon = getCodeHostIcon(repo.codeHostType); const repoImageSrc = repo.imageUrl ? getRepoImageSrc(repo.imageUrl, repo.id) : undefined; return ( @@ -192,7 +193,7 @@ export const columns: ColumnDef[] = [ const smallHash = hash.slice(0, 7); const repo = row.original; - const codeHostType = repo.codeHostType as CodeHostType; + const codeHostType = repo.codeHostType; const webUrl = repo.webUrl; const commitUrl = getCodeHostCommitUrl({ diff --git a/packages/web/src/app/[domain]/settings/connections/[id]/page.tsx b/packages/web/src/app/[domain]/settings/connections/[id]/page.tsx index 5db0d28c..c36a3342 100644 --- a/packages/web/src/app/[domain]/settings/connections/[id]/page.tsx +++ b/packages/web/src/app/[domain]/settings/connections/[id]/page.tsx @@ -7,7 +7,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip import { env } from "@/env.mjs"; import { SINGLE_TENANT_ORG_DOMAIN } from "@/lib/constants"; import { notFound, ServiceErrorException } from "@/lib/serviceError"; -import { CodeHostType, isServiceError } from "@/lib/utils"; +import { isServiceError } from "@/lib/utils"; import { withAuthV2 } from "@/withAuthV2"; import { AzureDevOpsConnectionConfig, BitbucketConnectionConfig, GenericGitHostConnectionConfig, GerritConnectionConfig, GiteaConnectionConfig, GithubConnectionConfig, GitlabConnectionConfig } from "@sourcebot/schemas/v3/index.type"; import { getConfigSettings } from "@sourcebot/shared"; @@ -47,8 +47,9 @@ export default async function ConnectionDetailPage(props: ConnectionDetailPagePr return undefined; })(); - const codeHostUrl = (() => { - const connectionType = connection.connectionType as CodeHostType; + // Extracts the code host URL from the connection config. + const codeHostUrl: string = (() => { + const connectionType = connection.connectionType; switch (connectionType) { case 'github': { const config = connection.config as unknown as GithubConnectionConfig; @@ -66,19 +67,19 @@ export default async function ConnectionDetailPage(props: ConnectionDetailPagePr const config = connection.config as unknown as GerritConnectionConfig; return config.url; } - case 'bitbucket-server': { + case 'bitbucket': { const config = connection.config as unknown as BitbucketConnectionConfig; - return config.url!; - } - case 'bitbucket-cloud': { - const config = connection.config as unknown as BitbucketConnectionConfig; - return config.url ?? 'https://bitbucket.org'; + if (config.deploymentType === 'cloud') { + return config.url ?? 'https://bitbucket.org'; + } else { + return config.url!; + } } case 'azuredevops': { const config = connection.config as unknown as AzureDevOpsConnectionConfig; return config.url ?? 'https://dev.azure.com'; } - case 'generic-git-host': { + case 'git': { const config = connection.config as unknown as GenericGitHostConnectionConfig; return config.url; } diff --git a/packages/web/src/app/[domain]/settings/connections/components/connectionsTable.tsx b/packages/web/src/app/[domain]/settings/connections/components/connectionsTable.tsx index 42897659..3285c71f 100644 --- a/packages/web/src/app/[domain]/settings/connections/components/connectionsTable.tsx +++ b/packages/web/src/app/[domain]/settings/connections/components/connectionsTable.tsx @@ -10,7 +10,8 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip" import { SINGLE_TENANT_ORG_DOMAIN } from "@/lib/constants" -import { CodeHostType, getCodeHostIcon } from "@/lib/utils" +import { getCodeHostIcon } from "@/lib/utils" +import { ConnectionType } from "@sourcebot/db" import { type ColumnDef, type ColumnFiltersState, @@ -35,7 +36,7 @@ export type Connection = { id: number name: string syncedAt: Date | null - codeHostType: CodeHostType + connectionType: ConnectionType latestJobStatus: "PENDING" | "IN_PROGRESS" | "COMPLETED" | "FAILED" | null isFirstTimeSync: boolean } @@ -80,13 +81,13 @@ export const columns: ColumnDef[] = [ }, cell: ({ row }) => { const connection = row.original; - const codeHostIcon = getCodeHostIcon(connection.codeHostType); + const codeHostIcon = getCodeHostIcon(connection.connectionType); return (
{`${connection.codeHostType} ({ id: connection.id, name: connection.name, - codeHostType: connection.connectionType as CodeHostType, + connectionType: connection.connectionType, syncedAt: connection.syncedAt, latestJobStatus: connection.latestJobStatus, isFirstTimeSync: connection.isFirstTimeSync, diff --git a/packages/web/src/app/[domain]/settings/secrets/components/importSecretCard.tsx b/packages/web/src/app/[domain]/settings/secrets/components/importSecretCard.tsx index f92e2712..4d9a5666 100644 --- a/packages/web/src/app/[domain]/settings/secrets/components/importSecretCard.tsx +++ b/packages/web/src/app/[domain]/settings/secrets/components/importSecretCard.tsx @@ -3,7 +3,8 @@ import { CodeHostIconButton } from "@/app/[domain]/components/codeHostIconButton"; import { Card, CardTitle, CardDescription, CardHeader, CardContent } from "@/components/ui/card"; import { getCodeHostIcon } from "@/lib/utils"; -import { cn, CodeHostType } from "@/lib/utils"; +import { cn } from "@/lib/utils"; +import { CodeHostType } from "@sourcebot/db"; import { useState } from "react"; import { ImportSecretDialog } from "@/app/[domain]/components/importSecretDialog"; import { useRouter } from "next/navigation"; diff --git a/packages/web/src/features/chat/components/searchScopeIcon.tsx b/packages/web/src/features/chat/components/searchScopeIcon.tsx index 67170dca..b134f8d4 100644 --- a/packages/web/src/features/chat/components/searchScopeIcon.tsx +++ b/packages/web/src/features/chat/components/searchScopeIcon.tsx @@ -1,4 +1,5 @@ -import { cn, CodeHostType, getCodeHostIcon } from "@/lib/utils"; +import { cn, getCodeHostIcon } from "@/lib/utils"; +import { CodeHostType } from "@sourcebot/db"; import { LibraryBigIcon } from "lucide-react"; import Image from "next/image"; import { SearchScope } from "../types"; diff --git a/packages/web/src/features/fileTree/actions.ts b/packages/web/src/features/fileTree/actions.ts index 003b82b2..6111ea70 100644 --- a/packages/web/src/features/fileTree/actions.ts +++ b/packages/web/src/features/fileTree/actions.ts @@ -263,7 +263,7 @@ const getRepoPath = (repo: Repo): { path: string, isReadOnly: boolean } => { // If we are dealing with a local repository, then use that as the path. // Mark as read-only since we aren't guaranteed to have write access to the local filesystem. const cloneUrl = new URL(repo.cloneUrl); - if (repo.external_codeHostType === 'generic-git-host' && cloneUrl.protocol === 'file:') { + if (repo.external_codeHostType === 'genericGitHost' && cloneUrl.protocol === 'file:') { return { path: cloneUrl.pathname, isReadOnly: true, diff --git a/packages/web/src/lib/utils.ts b/packages/web/src/lib/utils.ts index d3b450a0..5a48ce71 100644 --- a/packages/web/src/lib/utils.ts +++ b/packages/web/src/lib/utils.ts @@ -15,9 +15,10 @@ import { ServiceError } from "./serviceError"; import { StatusCodes } from "http-status-codes"; import { ErrorCode } from "./errorCodes"; import { NextRequest } from "next/server"; -import { Org } from "@sourcebot/db"; +import { ConnectionType, Org } from "@sourcebot/db"; import { OrgMetadata, orgMetadataSchema } from "@/types"; import { SINGLE_TENANT_ORG_DOMAIN } from "./constants"; +import { CodeHostType } from "@sourcebot/db"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) @@ -64,16 +65,6 @@ export const createPathWithQueryParams = (path: string, ...queryParams: [string, return `${path}?${queryString}`; } -export type CodeHostType = - "github" | - "gitlab" | - "gitea" | - "gerrit" | - "bitbucket-cloud" | - "bitbucket-server" | - "azuredevops" | - "generic-git-host"; - export type AuthProviderType = "github" | "gitlab" | @@ -248,9 +239,9 @@ export const getCodeHostInfoForRepo = (repo: { } } case "bitbucket-server": { - const { src, className } = getCodeHostIcon('bitbucket-server')!; + const { src, className } = getCodeHostIcon('bitbucketServer')!; return { - type: "bitbucket-server", + type: "bitbucketServer", displayName: displayName ?? name, codeHostName: "Bitbucket", repoLink: webUrl, @@ -259,9 +250,9 @@ export const getCodeHostInfoForRepo = (repo: { } } case "bitbucket-cloud": { - const { src, className } = getCodeHostIcon('bitbucket-cloud')!; + const { src, className } = getCodeHostIcon('bitbucketCloud')!; return { - type: "bitbucket-cloud", + type: "bitbucketCloud", displayName: displayName ?? name, codeHostName: "Bitbucket", repoLink: webUrl, @@ -270,9 +261,9 @@ export const getCodeHostInfoForRepo = (repo: { } } case "generic-git-host": { - const { src, className } = getCodeHostIcon('generic-git-host')!; + const { src, className } = getCodeHostIcon('genericGitHost')!; return { - type: "generic-git-host", + type: "genericGitHost", displayName: displayName ?? name, codeHostName: "Git Host", repoLink: webUrl, @@ -283,7 +274,7 @@ export const getCodeHostInfoForRepo = (repo: { } } -export const getCodeHostIcon = (codeHostType: CodeHostType): { src: string, className?: string } => { +export const getCodeHostIcon = (codeHostType: CodeHostType | ConnectionType): { src: string, className?: string } => { switch (codeHostType) { case "github": return { @@ -302,8 +293,9 @@ export const getCodeHostIcon = (codeHostType: CodeHostType): { src: string, clas return { src: gerritLogo, } - case "bitbucket-cloud": - case "bitbucket-server": + case "bitbucket": + case "bitbucketCloud": + case "bitbucketServer": return { src: bitbucketLogo, } @@ -311,7 +303,8 @@ export const getCodeHostIcon = (codeHostType: CodeHostType): { src: string, clas return { src: azuredevopsLogo, } - case "generic-git-host": + case "git": + case "genericGitHost": return { src: gitLogo, } @@ -340,13 +333,13 @@ export const getCodeHostCommitUrl = ({ return `${webUrl}/commit/${commitHash}`; case 'azuredevops': return `${webUrl}/commit/${commitHash}`; - case 'bitbucket-cloud': + case 'bitbucketCloud': return `${webUrl}/commits/${commitHash}`; - case 'bitbucket-server': + case 'bitbucketServer': return `${webUrl}/commits/${commitHash}`; case 'gerrit': return `${webUrl}/+/${commitHash}`; - case 'generic-git-host': + case 'genericGitHost': return undefined; } } @@ -373,13 +366,13 @@ export const getCodeHostBrowseAtBranchUrl = ({ return `${webUrl}/src/branch/${branchName}`; case 'azuredevops': return `${webUrl}?branch=${branchName}`; - case 'bitbucket-cloud': + case 'bitbucketCloud': return `${webUrl}?at=${branchName}`; - case 'bitbucket-server': + case 'bitbucketServer': return `${webUrl}?at=${branchName}`; case 'gerrit': return `${webUrl}/+/${branchName}`; - case 'generic-git-host': + case 'genericGitHost': return undefined; } } @@ -389,11 +382,11 @@ export const isAuthSupportedForCodeHost = (codeHostType: CodeHostType): boolean case "github": case "gitlab": case "gitea": - case "bitbucket-cloud": - case "bitbucket-server": + case "bitbucketCloud": + case "bitbucketServer": case "azuredevops": return true; - case "generic-git-host": + case "genericGitHost": case "gerrit": return false; }