(
projectId: string,
projectName: string,
options?: { githubRepo?: string | null; teamId?: string | null },
)
| 172 | } |
| 173 | |
| 174 | export async function connectVercelProject( |
| 175 | projectId: string, |
| 176 | projectName: string, |
| 177 | options?: { githubRepo?: string | null; teamId?: string | null }, |
| 178 | ) { |
| 179 | const token = await getPlainServiceToken('vercel'); |
| 180 | if (!token) { |
| 181 | throw new VercelError('Vercel token not configured', 401); |
| 182 | } |
| 183 | |
| 184 | const project = await getProjectById(projectId); |
| 185 | if (!project) { |
| 186 | throw new VercelError('Project not found', 404); |
| 187 | } |
| 188 | |
| 189 | const teamId = options?.teamId ?? null; |
| 190 | |
| 191 | let linkedRepo = options?.githubRepo ?? null; |
| 192 | if (!linkedRepo) { |
| 193 | const githubRepo = await getProjectGitHubRepo(projectId); |
| 194 | if (githubRepo) { |
| 195 | linkedRepo = githubRepo.fullName; |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | const payload: Record<string, unknown> = { |
| 200 | name: projectName, |
| 201 | framework: 'nextjs', |
| 202 | }; |
| 203 | |
| 204 | if (linkedRepo) { |
| 205 | payload.gitRepository = { |
| 206 | type: 'github', |
| 207 | repo: linkedRepo, |
| 208 | }; |
| 209 | } |
| 210 | |
| 211 | let vercelProject: VercelProjectResponse | null = null; |
| 212 | |
| 213 | try { |
| 214 | vercelProject = await vercelFetch<VercelProjectResponse>( |
| 215 | token, |
| 216 | '/v10/projects', |
| 217 | { |
| 218 | method: 'POST', |
| 219 | body: payload, |
| 220 | teamId, |
| 221 | }, |
| 222 | ); |
| 223 | } catch (error) { |
| 224 | if (error instanceof VercelError && error.status === 409) { |
| 225 | vercelProject = await fetchExistingProject(token, projectName, teamId); |
| 226 | } else { |
| 227 | throw error; |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | if (!vercelProject) { |
no test coverage detected